From 871eb4814b2dbe5f6a5315a59a23f6c351c34998 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 30 Oct 2015 16:34:23 +1100 Subject: [PATCH] Speed up Bitmap decoding Former-commit-id: 8fe4bf1334dcb4589d5d6a7d1eae7ddbad9d647b Former-commit-id: a35a47453657a8961fa95c5fd7e071dea649a7b0 Former-commit-id: 2c5e5865acd0c53cf2076f35a0289e9e5eda2b7e --- src/ImageProcessor/Formats/Bmp/BmpDecoder.cs | 5 +- .../Formats/Bmp/BmpDecoderCore.cs | 107 ++++++++++-------- src/ImageProcessor/Formats/Bmp/BmpEncoder.cs | 1 - 3 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/ImageProcessor/Formats/Bmp/BmpDecoder.cs b/src/ImageProcessor/Formats/Bmp/BmpDecoder.cs index cc1b6b464a..2e47b607a6 100644 --- a/src/ImageProcessor/Formats/Bmp/BmpDecoder.cs +++ b/src/ImageProcessor/Formats/Bmp/BmpDecoder.cs @@ -67,9 +67,8 @@ namespace ImageProcessor.Formats bool isBmp = false; if (header.Length >= 2) { - isBmp = - header[0] == 0x42 && // B - header[1] == 0x4D; // M + isBmp = header[0] == 0x42 && // B + header[1] == 0x4D; // M } return isBmp; diff --git a/src/ImageProcessor/Formats/Bmp/BmpDecoderCore.cs b/src/ImageProcessor/Formats/Bmp/BmpDecoderCore.cs index ca04f2b453..fe4a7c8891 100644 --- a/src/ImageProcessor/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageProcessor/Formats/Bmp/BmpDecoderCore.cs @@ -250,31 +250,34 @@ namespace ImageProcessor.Formats int alignment; byte[] data = this.GetImageArray(width, height, 2, out alignment); - for (int y = 0; y < height; y++) - { - int rowOffset = y * ((width * 2) + alignment); + Parallel.For( + 0, + height, + y => + { + int rowOffset = y * ((width * 2) + alignment); - // Revert the y value, because bitmaps are saved from down to top - int row = Invert(y, height); + // Revert the y value, because bitmaps are saved from down to top + int row = Invert(y, height); - for (int x = 0; x < width; x++) - { - int offset = rowOffset + (x * 2); + for (int x = 0; x < width; x++) + { + int offset = rowOffset + (x * 2); - short temp = BitConverter.ToInt16(data, offset); + short temp = BitConverter.ToInt16(data, offset); - byte r = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR); - byte g = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG); - byte b = (byte)((temp & Rgb16BMask) * ScaleR); + byte r = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR); + byte g = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG); + byte b = (byte)((temp & Rgb16BMask) * ScaleR); - int arrayOffset = ((row * width) + x) * 4; + int arrayOffset = ((row * width) + x) * 4; - imageData[arrayOffset + 0] = b; - imageData[arrayOffset + 1] = g; - imageData[arrayOffset + 2] = r; - imageData[arrayOffset + 3] = 255; - } - } + imageData[arrayOffset + 0] = b; + imageData[arrayOffset + 1] = g; + imageData[arrayOffset + 2] = r; + imageData[arrayOffset + 3] = 255; + } + }); } /// @@ -288,24 +291,27 @@ namespace ImageProcessor.Formats int alignment; byte[] data = this.GetImageArray(width, height, 3, out alignment); - for (int y = 0; y < height; y++) - { - int rowOffset = y * ((width * 3) + alignment); + Parallel.For( + 0, + height, + y => + { + int rowOffset = y * ((width * 3) + alignment); - // Revert the y value, because bitmaps are saved from down to top - int row = Invert(y, height); + // Revert the y value, because bitmaps are saved from down to top + int row = Invert(y, height); - for (int x = 0; x < width; x++) - { - int offset = rowOffset + (x * 3); - int arrayOffset = ((row * width) + x) * 4; + for (int x = 0; x < width; x++) + { + int offset = rowOffset + (x * 3); + int arrayOffset = ((row * width) + x) * 4; - imageData[arrayOffset + 0] = data[offset + 0]; - imageData[arrayOffset + 1] = data[offset + 1]; - imageData[arrayOffset + 2] = data[offset + 2]; - imageData[arrayOffset + 3] = 255; - } - } + imageData[arrayOffset + 0] = data[offset + 0]; + imageData[arrayOffset + 1] = data[offset + 1]; + imageData[arrayOffset + 2] = data[offset + 2]; + imageData[arrayOffset + 3] = 255; + } + }); } /// @@ -319,24 +325,27 @@ namespace ImageProcessor.Formats int alignment; byte[] data = this.GetImageArray(width, height, 4, out alignment); - for (int y = 0; y < height; y++) - { - int rowOffset = y * ((width * 4) + alignment); + Parallel.For( + 0, + height, + y => + { + int rowOffset = y * ((width * 4) + alignment); - // Revert the y value, because bitmaps are saved from down to top - int row = Invert(y, height); + // Revert the y value, because bitmaps are saved from down to top + int row = Invert(y, height); - for (int x = 0; x < width; x++) - { - int offset = rowOffset + (x * 4); + for (int x = 0; x < width; x++) + { + int offset = rowOffset + (x * 4); - var arrayOffset = ((row * width) + x) * 4; - imageData[arrayOffset + 0] = data[offset + 0]; - imageData[arrayOffset + 1] = data[offset + 1]; - imageData[arrayOffset + 2] = data[offset + 2]; - imageData[arrayOffset + 3] = 255; // Can we get alpha here? - } - } + var arrayOffset = ((row * width) + x) * 4; + imageData[arrayOffset + 0] = data[offset + 0]; + imageData[arrayOffset + 1] = data[offset + 1]; + imageData[arrayOffset + 2] = data[offset + 2]; + imageData[arrayOffset + 3] = 255; // Can we get alpha here? + } + }); } /// diff --git a/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs b/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs index bbb2d65383..ed833bf620 100644 --- a/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs +++ b/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs @@ -7,7 +7,6 @@ namespace ImageProcessor.Formats { using System; using System.IO; - using System.Threading.Tasks; /// /// Image encoder for writing an image to a stream as a Windows bitmap.