From e8b29a2e98ecb2e4db78f77f9cd007d2d60c11c3 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 16 May 2019 20:08:16 +0200 Subject: [PATCH] Refactor Write8Bit into two methods: one for gray and one for color --- src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs | 140 ++++++++++++------- 1 file changed, 86 insertions(+), 54 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index 532d20e00..e9600f640 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -311,68 +311,100 @@ namespace SixLabors.ImageSharp.Formats.Bmp Span colorPalette = colorPaletteBuffer.GetSpan(); if (isGray8) { - for (byte i = 0; i <= 255; i++) - { - int idx = i * 4; - colorPalette[idx] = i; - colorPalette[idx + 1] = i; - colorPalette[idx + 2] = i; + this.Write8BitGray(stream, image, colorPalette); + } + else + { + this.Write8BitColor(stream, image, colorPalette); + } + } + } - // Padding byte, always 0 - colorPalette[idx + 3] = 0; - } + /// + /// Writes an 8 Bit color image with a color palette. The color palette has 256 entry's with 4 bytes for each entry. + /// + /// The type of the pixel. + /// The to write to. + /// The containing pixel data. + /// A byte span of size 1024 for the color palette. + private void Write8BitColor(Stream stream, ImageFrame image, Span colorPalette) + where TPixel : struct, IPixel + { + using (IQuantizedFrame quantized = this.quantizer.CreateFrameQuantizer(this.configuration, 256).QuantizeFrame(image)) + { + ReadOnlySpan quantizedColors = quantized.Palette.Span; + var color = default(Rgba32); - stream.Write(colorPalette); + // TODO: Use bulk conversion here for better perf + int idx = 0; + foreach (TPixel quantizedColor in quantizedColors) + { + quantizedColor.ToRgba32(ref color); + colorPalette[idx] = color.B; + colorPalette[idx + 1] = color.G; + colorPalette[idx + 2] = color.R; + + // Padding byte, always 0. + colorPalette[idx + 3] = 0; + idx += 4; + } - using (IMemoryOwner rowSpanBuffer = this.memoryAllocator.AllocateManagedByteBuffer(image.Width, AllocationOptions.Clean)) + stream.Write(colorPalette); + + for (int y = image.Height - 1; y >= 0; y--) + { + ReadOnlySpan pixelSpan = quantized.GetRowSpan(y); + stream.Write(pixelSpan); + + for (int i = 0; i < this.padding; i++) { - Span outputPixelRow = rowSpanBuffer.GetSpan(); - for (int y = image.Height - 1; y >= 0; y--) - { - Span inputPixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToGray8Bytes(this.configuration, inputPixelRow, outputPixelRow, image.Width); - stream.Write(outputPixelRow); - - for (int i = 0; i < this.padding; i++) - { - stream.WriteByte(0); - } - } + stream.WriteByte(0); } } - else + } + } + + /// + /// Writes an 8 Bit gray image with a color palette. The color palette has 256 entry's with 4 bytes for each entry. + /// + /// The type of the pixel. + /// The to write to. + /// The containing pixel data. + /// A byte span of size 1024 for the color palette. + private void Write8BitGray(Stream stream, ImageFrame image, Span colorPalette) + where TPixel : struct, IPixel + { + // Create a color palette with 256 different gray values. + for (int i = 0; i <= 255; i++) + { + int idx = i * 4; + byte grayValue = (byte)i; + colorPalette[idx] = grayValue; + colorPalette[idx + 1] = grayValue; + colorPalette[idx + 2] = grayValue; + + // Padding byte, always 0. + colorPalette[idx + 3] = 0; + } + + stream.Write(colorPalette); + + using (IMemoryOwner rowSpanBuffer = this.memoryAllocator.AllocateManagedByteBuffer(image.Width, AllocationOptions.Clean)) + { + Span outputPixelRow = rowSpanBuffer.GetSpan(); + for (int y = image.Height - 1; y >= 0; y--) { - using (IQuantizedFrame quantized = this.quantizer.CreateFrameQuantizer(this.configuration, 256).QuantizeFrame(image)) + Span inputPixelRow = image.GetPixelRowSpan(y); + PixelOperations.Instance.ToGray8Bytes( + this.configuration, + inputPixelRow, + outputPixelRow, + image.Width); + stream.Write(outputPixelRow); + + for (int i = 0; i < this.padding; i++) { - ReadOnlySpan quantizedColors = quantized.Palette.Span; - var color = default(Rgba32); - - // TODO: Use bulk conversion here for better perf - int idx = 0; - foreach (TPixel quantizedColor in quantizedColors) - { - quantizedColor.ToRgba32(ref color); - colorPalette[idx] = color.B; - colorPalette[idx + 1] = color.G; - colorPalette[idx + 2] = color.R; - - // Padding byte, always 0 - colorPalette[idx + 3] = 0; - idx += 4; - } - - stream.Write(colorPalette); - - for (int y = image.Height - 1; y >= 0; y--) - { - ReadOnlySpan pixelSpan = quantized.GetRowSpan(y); - stream.Write(pixelSpan); - - for (int i = 0; i < this.padding; i++) - { - stream.WriteByte(0); - } - } + stream.WriteByte(0); } } }