diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index 42a350c151..66c8b6c086 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -55,9 +55,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp this.padding = bytesPerLine - (image.Width * (int)this.bitsPerPixel); // Do not use IDisposable pattern here as we want to preserve the stream. - var writer = new LittleEndianBinaryWriter(stream); + EndianBinaryWriter writer = new EndianBinaryWriter(Endianness.LittleEndian, stream); - var infoHeader = new BmpInfoHeader + BmpInfoHeader infoHeader = new BmpInfoHeader { HeaderSize = BmpInfoHeader.BitmapInfoHeaderSize, Height = image.Height, @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp ClrImportant = 0 }; - var fileHeader = new BmpFileHeader + BmpFileHeader fileHeader = new BmpFileHeader { Type = 19778, // BM Offset = 54, @@ -87,12 +87,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// Writes the bitmap header data to the binary stream. /// /// - /// The containing the stream to write to. + /// The containing the stream to write to. /// /// /// The containing the header data. /// - private static void WriteHeader(LittleEndianBinaryWriter writer, BmpFileHeader fileHeader) + private static void WriteHeader(EndianBinaryWriter writer, BmpFileHeader fileHeader) { writer.Write(fileHeader.Type); writer.Write(fileHeader.FileSize); @@ -104,12 +104,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// Writes the bitmap information to the binary stream. /// /// - /// The containing the stream to write to. + /// The containing the stream to write to. /// /// /// The containing the detailed information about the image. /// - private void WriteInfo(LittleEndianBinaryWriter writer, BmpInfoHeader infoHeader) + private void WriteInfo(EndianBinaryWriter writer, BmpInfoHeader infoHeader) { writer.Write(infoHeader.HeaderSize); writer.Write(infoHeader.Width); @@ -128,11 +128,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// Writes the pixel data to the binary stream. /// /// The pixel format. - /// The containing the stream to write to. + /// The containing the stream to write to. /// /// The containing pixel data. /// - private void WriteImage(LittleEndianBinaryWriter writer, ImageFrame image) + private void WriteImage(EndianBinaryWriter writer, ImageFrame image) where TPixel : struct, IPixel { using (PixelAccessor pixels = image.Lock()) @@ -159,9 +159,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 containing the stream to write to. /// The containing pixel data. - private void Write32Bit(LittleEndianBinaryWriter writer, PixelAccessor pixels) + private void Write32Bit(EndianBinaryWriter writer, PixelAccessor pixels) where TPixel : struct, IPixel { using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 4)) @@ -179,9 +179,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 containing the stream to write to. /// The containing pixel data. - private void Write24Bit(LittleEndianBinaryWriter writer, PixelAccessor pixels) + private void Write24Bit(EndianBinaryWriter writer, PixelAccessor pixels) where TPixel : struct, IPixel { using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 3)) diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index 5472b3fd4a..7550d0669a 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Formats.Gif Guard.NotNull(stream, nameof(stream)); // Do not use IDisposable pattern here as we want to preserve the stream. - var writer = new LittleEndianBinaryWriter(stream); + var writer = new EndianBinaryWriter(Endianness.LittleEndian, stream); this.hasFrames = image.Frames.Count > 1; @@ -155,7 +155,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// Writes the file header signature and version to the stream. /// /// The writer to write to the stream with. - private void WriteHeader(LittleEndianBinaryWriter writer) + private void WriteHeader(EndianBinaryWriter writer) { writer.Write(GifConstants.MagicNumber, 0, GifConstants.MagicNumber.Length); } @@ -167,7 +167,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The image to encode. /// The writer to write to the stream with. /// The transparency index to set the default background index to. - private void WriteLogicalScreenDescriptor(Image image, LittleEndianBinaryWriter writer, int transparencyIndex) + private void WriteLogicalScreenDescriptor(Image image, EndianBinaryWriter writer, int transparencyIndex) where TPixel : struct, IPixel { var descriptor = new GifLogicalScreenDescriptor @@ -202,7 +202,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The writer to write to the stream with. /// The animated image repeat count. /// The number of image frames. - private void WriteApplicationExtension(LittleEndianBinaryWriter writer, ushort repeatCount, int frames) + private void WriteApplicationExtension(EndianBinaryWriter writer, ushort repeatCount, int frames) { // Application Extension Header if (repeatCount != 1 && frames > 0) @@ -231,7 +231,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The pixel format. /// The to be encoded. /// The stream to write to. - private void WriteComments(Image image, LittleEndianBinaryWriter writer) + private void WriteComments(Image image, EndianBinaryWriter writer) where TPixel : struct, IPixel { if (this.ignoreMetadata) @@ -264,7 +264,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The metadata of the image or frame. /// The stream to write to. /// The index of the color in the color palette to make transparent. - private void WriteGraphicalControlExtension(ImageFrameMetaData metaData, LittleEndianBinaryWriter writer, int transparencyIndex) + private void WriteGraphicalControlExtension(ImageFrameMetaData metaData, EndianBinaryWriter writer, int transparencyIndex) { var extension = new GifGraphicsControlExtension { @@ -299,7 +299,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The pixel format. /// The to be encoded. /// The stream to write to. - private void WriteImageDescriptor(ImageFrame image, LittleEndianBinaryWriter writer) + private void WriteImageDescriptor(ImageFrame image, EndianBinaryWriter writer) where TPixel : struct, IPixel { writer.Write(GifConstants.ImageDescriptorLabel); // 2c @@ -325,7 +325,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The pixel format. /// The to encode. /// The writer to write to the stream with. - private void WriteColorTable(QuantizedFrame image, LittleEndianBinaryWriter writer) + private void WriteColorTable(QuantizedFrame image, EndianBinaryWriter writer) where TPixel : struct, IPixel { // Grab the palette and write it to the stream. @@ -357,7 +357,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The pixel format. /// The containing indexed pixels. /// The stream to write to. - private void WriteImageData(QuantizedFrame image, LittleEndianBinaryWriter writer) + private void WriteImageData(QuantizedFrame image, EndianBinaryWriter writer) where TPixel : struct, IPixel { using (var encoder = new LzwEncoder(this.memoryManager, image.Pixels, (byte)this.bitDepth)) diff --git a/src/ImageSharp/IO/BigEndianBinaryWriter.cs b/src/ImageSharp/IO/BigEndianBinaryWriter.cs deleted file mode 100644 index a3de655570..0000000000 --- a/src/ImageSharp/IO/BigEndianBinaryWriter.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Buffers.Binary; -using System.IO; - -namespace SixLabors.ImageSharp.IO -{ - /// - /// A BigEndian variant of - /// - internal sealed class BigEndianBinaryWriter : EndianBinaryWriter - { - /// - /// Initializes a new instance of the class - /// - /// Stream to write data to - public BigEndianBinaryWriter(Stream stream) - : base(stream) - { - } - - /// - public override Endianness Endianness => Endianness.BigEndian; - - /// - public override void Write(short value) - { - BinaryPrimitives.WriteInt16BigEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 2); - } - - /// - public override void Write(int value) - { - BinaryPrimitives.WriteInt32BigEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 4); - } - - /// - public override void Write(long value) - { - BinaryPrimitives.WriteInt64BigEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 8); - } - - /// - public override void Write(ushort value) - { - BinaryPrimitives.WriteUInt16BigEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 2); - } - - /// - public override void Write(uint value) - { - BinaryPrimitives.WriteUInt32BigEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 4); - } - - /// - public override void Write(ulong value) - { - BinaryPrimitives.WriteUInt64BigEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 8); - } - - /// - public override unsafe void Write(float value) - { - this.Write(*((int*)&value)); - } - - /// - public override unsafe void Write(double value) - { - this.Write(*((long*)&value)); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/IO/EndianBinaryWriter.cs b/src/ImageSharp/IO/EndianBinaryWriter.cs index 1366764de5..9c42f0b694 100644 --- a/src/ImageSharp/IO/EndianBinaryWriter.cs +++ b/src/ImageSharp/IO/EndianBinaryWriter.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.IO @@ -9,12 +10,17 @@ namespace SixLabors.ImageSharp.IO /// /// Equivalent of , but with either endianness /// - internal abstract class EndianBinaryWriter : IDisposable + internal class EndianBinaryWriter : IDisposable { /// /// Buffer used for temporary storage during conversion from primitives /// - protected readonly byte[] buffer = new byte[16]; + private readonly byte[] buffer = new byte[16]; + + /// + /// The endianness used to write the data + /// + private readonly Endianness endianness; /// /// Whether or not this writer has been disposed yet. @@ -23,14 +29,17 @@ namespace SixLabors.ImageSharp.IO /// /// Initializes a new instance of the class + /// with the given bit converter, writing to the given stream, using the given encoding. /// + /// Endianness to use when writing data /// Stream to write data to - public EndianBinaryWriter(Stream stream) + public EndianBinaryWriter(Endianness endianness, Stream stream) { Guard.NotNull(stream, nameof(stream)); Guard.IsTrue(stream.CanWrite, nameof(stream), "Stream isn't writable"); this.BaseStream = stream; + this.endianness = endianness; } /// @@ -38,11 +47,6 @@ namespace SixLabors.ImageSharp.IO /// public Stream BaseStream { get; } - /// - /// Gets the endianness of the BinaryWriter - /// - public abstract Endianness Endianness { get; } - /// /// Closes the writer, including the underlying stream. /// @@ -87,56 +91,134 @@ namespace SixLabors.ImageSharp.IO /// for this writer. 2 bytes are written. /// /// The value to write - public abstract void Write(short value); + public void Write(short value) + { + if (this.endianness == Endianness.BigEndian) + { + BinaryPrimitives.WriteInt16BigEndian(this.buffer, value); + } + else + { + BinaryPrimitives.WriteInt16LittleEndian(this.buffer, value); + } + + this.WriteInternal(this.buffer, 2); + } /// /// Writes a 32-bit signed integer to the stream, using the bit converter /// for this writer. 4 bytes are written. /// /// The value to write - public abstract void Write(int value); + public void Write(int value) + { + if (this.endianness == Endianness.BigEndian) + { + BinaryPrimitives.WriteInt32BigEndian(this.buffer, value); + } + else + { + BinaryPrimitives.WriteInt32LittleEndian(this.buffer, value); + } + + this.WriteInternal(this.buffer, 4); + } /// /// Writes a 64-bit signed integer to the stream, using the bit converter /// for this writer. 8 bytes are written. /// /// The value to write - public abstract void Write(long value); + public void Write(long value) + { + if (this.endianness == Endianness.BigEndian) + { + BinaryPrimitives.WriteInt64BigEndian(this.buffer, value); + } + else + { + BinaryPrimitives.WriteInt64LittleEndian(this.buffer, value); + } + + this.WriteInternal(this.buffer, 8); + } /// /// Writes a 16-bit unsigned integer to the stream, using the bit converter /// for this writer. 2 bytes are written. /// /// The value to write - public abstract void Write(ushort value); + public void Write(ushort value) + { + if (this.endianness == Endianness.BigEndian) + { + BinaryPrimitives.WriteUInt16BigEndian(this.buffer, value); + } + else + { + BinaryPrimitives.WriteUInt16LittleEndian(this.buffer, value); + } + + this.WriteInternal(this.buffer, 2); + } /// /// Writes a 32-bit unsigned integer to the stream, using the bit converter /// for this writer. 4 bytes are written. /// /// The value to write - public abstract void Write(uint value); + public void Write(uint value) + { + if (this.endianness == Endianness.BigEndian) + { + BinaryPrimitives.WriteUInt32BigEndian(this.buffer, value); + } + else + { + BinaryPrimitives.WriteUInt32LittleEndian(this.buffer, value); + } + + this.WriteInternal(this.buffer, 4); + } /// /// Writes a 64-bit unsigned integer to the stream, using the bit converter /// for this writer. 8 bytes are written. /// /// The value to write - public abstract void Write(ulong value); + public void Write(ulong value) + { + if (this.endianness == Endianness.BigEndian) + { + BinaryPrimitives.WriteUInt64BigEndian(this.buffer, value); + } + else + { + BinaryPrimitives.WriteUInt64LittleEndian(this.buffer, value); + } + + this.WriteInternal(this.buffer, 8); + } /// /// Writes a single-precision floating-point value to the stream, using the bit converter /// for this writer. 4 bytes are written. /// /// The value to write - public abstract void Write(float value); + public unsafe void Write(float value) + { + this.Write(*((int*)&value)); + } /// /// Writes a double-precision floating-point value to the stream, using the bit converter /// for this writer. 8 bytes are written. /// /// The value to write - public abstract void Write(double value); + public unsafe void Write(double value) + { + this.Write(*((long*)&value)); + } /// /// Writes a signed byte to the stream. @@ -202,7 +284,7 @@ namespace SixLabors.ImageSharp.IO { if (this.disposed) { - throw new ObjectDisposedException(nameof(BigEndianBinaryWriter)); + throw new ObjectDisposedException(nameof(EndianBinaryWriter)); } } @@ -212,22 +294,10 @@ namespace SixLabors.ImageSharp.IO /// /// The array of bytes to write from /// The number of bytes to write - protected void WriteInternal(byte[] bytes, int length) + private void WriteInternal(byte[] bytes, int length) { this.CheckDisposed(); this.BaseStream.Write(bytes, 0, length); } - - public static EndianBinaryWriter Create(Endianness endianness, Stream stream) - { - if (endianness == Endianness.BigEndian) - { - return new BigEndianBinaryWriter(stream); - } - else - { - return new LittleEndianBinaryWriter(stream); - } - } } } \ No newline at end of file diff --git a/src/ImageSharp/IO/LittleEndianBinaryWriter.cs b/src/ImageSharp/IO/LittleEndianBinaryWriter.cs deleted file mode 100644 index 7be137fb00..0000000000 --- a/src/ImageSharp/IO/LittleEndianBinaryWriter.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Buffers.Binary; -using System.IO; - -namespace SixLabors.ImageSharp.IO -{ - /// - /// A Little Endian variant of - /// - internal sealed class LittleEndianBinaryWriter : EndianBinaryWriter - { - /// - /// Initializes a new instance of the class - /// - /// Stream to write data to - public LittleEndianBinaryWriter(Stream stream) - : base(stream) - { - } - - /// - public override Endianness Endianness => Endianness.LittleEndian; - - /// - public override void Write(short value) - { - BinaryPrimitives.WriteInt16LittleEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 2); - } - - /// - public override void Write(int value) - { - BinaryPrimitives.WriteInt32LittleEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 4); - } - - /// - public override void Write(long value) - { - BinaryPrimitives.WriteInt64LittleEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 8); - } - - /// - public override void Write(ushort value) - { - BinaryPrimitives.WriteUInt16LittleEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 2); - } - - /// - public override void Write(uint value) - { - BinaryPrimitives.WriteUInt32LittleEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 4); - } - - /// - public override void Write(ulong value) - { - BinaryPrimitives.WriteUInt64LittleEndian(this.buffer, value); - - this.WriteInternal(this.buffer, 8); - } - - /// - public override unsafe void Write(float value) - { - this.Write(*((int*)&value)); - } - - /// - public override unsafe void Write(double value) - { - this.Write(*((long*)&value)); - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs b/tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs index 2712baafad..6e22b16891 100644 --- a/tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs +++ b/tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Tests.IO { var stream = new MemoryStream(); - using (var writer = EndianBinaryWriter.Create(endianness, stream)) + using (var writer = new EndianBinaryWriter(endianness, stream)) { writer.Write((float)Math.PI); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.IO { var stream = new MemoryStream(); - using (var writer = EndianBinaryWriter.Create(endianness, stream)) + using (var writer = new EndianBinaryWriter(endianness, stream)) { writer.Write(Math.PI); @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Tests.IO { var stream = new MemoryStream(); - var writer = EndianBinaryWriter.Create(endianness, stream); + var writer = new EndianBinaryWriter(endianness, stream); writer.Write(true); // Bool writer.Write((byte)1); // Byte