diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs index f193aa598c..6c46f2d6b7 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs @@ -20,6 +20,11 @@ namespace ImageProcessorCore.Formats /// private BmpBitsPerPixel bmpBitsPerPixel; + /// + /// The amount to pad each row by. + /// + private int padding; + /// /// Encodes the image to the specified stream from the . /// @@ -37,39 +42,33 @@ namespace ImageProcessorCore.Formats this.bmpBitsPerPixel = bitsPerPixel; - int rowWidth = image.Width; - - // TODO: Check this for varying file formats. - int amount = (image.Width * (int)this.bmpBitsPerPixel) % 4; - if (amount != 0) - { - rowWidth += 4 - amount; - } + // Cast to int will get the bytes per pixel + short bpp = (short)(8 * (int)bitsPerPixel); + int bytesPerLine = 4 * ((image.Width * bpp + 31) / 32); + this.padding = bytesPerLine - (image.Width * (int)bitsPerPixel); - // Do not use IDisposable pattern here as we want to preserve the stream. + // Do not use IDisposable pattern here as we want to preserve the stream. EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Little, stream); - int bpp = (int)this.bmpBitsPerPixel; - - BmpFileHeader fileHeader = new BmpFileHeader - { - Type = 19778, // BM - Offset = 54, - FileSize = 54 + (image.Height * rowWidth * bpp) - }; - BmpInfoHeader infoHeader = new BmpInfoHeader { - HeaderSize = 40, + HeaderSize = BmpInfoHeader.Size, Height = image.Height, Width = image.Width, - BitsPerPixel = (short)(8 * bpp), + BitsPerPixel = bpp, Planes = 1, - ImageSize = image.Height * rowWidth * bpp, + ImageSize = image.Height * bytesPerLine, ClrUsed = 0, ClrImportant = 0 }; + BmpFileHeader fileHeader = new BmpFileHeader + { + Type = 19778, // BM + Offset = 54, + FileSize = 54 + infoHeader.ImageSize + }; + WriteHeader(writer, fileHeader); this.WriteInfo(writer, infoHeader); this.WriteImage(writer, image); @@ -132,23 +131,16 @@ namespace ImageProcessorCore.Formats where T : IPackedVector where TP : struct { - // TODO: Add more compression formats. - int amount = (image.Width * (int)this.bmpBitsPerPixel) % 4; - if (amount != 0) - { - amount = 4 - amount; - } - using (IPixelAccessor pixels = image.Lock()) { - switch (this.bmpBitsPerPixel) + switch (bmpBitsPerPixel) { case BmpBitsPerPixel.Pixel32: - this.Write32bit(writer, pixels, amount); + this.Write32bit(writer, pixels); break; case BmpBitsPerPixel.Pixel24: - this.Write24bit(writer, pixels, amount); + this.Write24bit(writer, pixels); break; } } @@ -161,8 +153,7 @@ namespace ImageProcessorCore.Formats /// The packed format. long, float. /// The containing the stream to write to. /// The containing pixel data. - /// The amount to pad each row by. - private void Write32bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) + private void Write32bit(EndianBinaryWriter writer, IPixelAccessor pixels) where T : IPackedVector where TP : struct { @@ -176,7 +167,7 @@ namespace ImageProcessorCore.Formats } // Pad - for (int i = 0; i < amount; i++) + for (int i = 0; i < this.padding; i++) { writer.Write((byte)0); } @@ -189,8 +180,7 @@ namespace ImageProcessorCore.Formats /// The pixel format. /// The packed format. long, float./// The containing the stream to write to. /// The containing pixel data. - /// The amount to pad each row by. - private void Write24bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) + private void Write24bit(EndianBinaryWriter writer, IPixelAccessor pixels) where T : IPackedVector where TP : struct { @@ -204,7 +194,7 @@ namespace ImageProcessorCore.Formats } // Pad - for (int i = 0; i < amount; i++) + for (int i = 0; i < this.padding; i++) { writer.Write((byte)0); }