diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
index 39bab442f..04176e033 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
@@ -12,22 +12,25 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
/// Performs the bmp decoding operation.
///
+ ///
+ /// A useful decoding source example can be found at
+ ///
internal sealed class BmpDecoderCore
{
///
/// The mask for the red part of the color for 16 bit rgb bitmaps.
///
- private const int Rgb16RMask = 0x00007C00;
+ private const int Rgb16RMask = 0x7C00;
///
/// The mask for the green part of the color for 16 bit rgb bitmaps.
///
- private const int Rgb16GMask = 0x000003E0;
+ private const int Rgb16GMask = 0x3E0;
///
/// The mask for the blue part of the color for 16 bit rgb bitmaps.
///
- private const int Rgb16BMask = 0x0000001F;
+ private const int Rgb16BMask = 0x1F;
///
/// RLE8 flag value that indicates following byte has special meaning
@@ -233,6 +236,17 @@ namespace SixLabors.ImageSharp.Formats.Bmp
return padding;
}
+ ///
+ /// Performs final shifting from a 5bit value to an 8bit one.
+ ///
+ /// The masked and shifted value
+ /// The
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static byte GetBytesFrom5BitValue(int value)
+ {
+ return (byte)((value << 3) | (value >> 2));
+ }
+
///
/// Looks up color values and builds the image from de-compressed RLE8 data.
/// Compresssed RLE8 stream is uncompressed by
@@ -416,36 +430,31 @@ namespace SixLabors.ImageSharp.Formats.Bmp
private void ReadRgb16(PixelAccessor pixels, int width, int height, bool inverted)
where TPixel : struct, IPixel
{
- // We divide here as we will store the colors in our floating point format.
- const int ScaleR = 8; // 256/32
- const int ScaleG = 4; // 256/64
- const int ComponentCount = 2;
-
+ int padding = CalculatePadding(width, 2);
+ int stride = (width * 2) + padding;
var color = default(TPixel);
var rgba = new Rgba32(0, 0, 0, 255);
- using (var row = new PixelArea(width, ComponentOrder.Xyz))
+ using (var buffer = new Buffer(stride))
{
for (int y = 0; y < height; y++)
{
- row.Read(this.currentStream);
-
+ this.currentStream.Read(buffer.Array, 0, stride);
int newY = Invert(y, height, inverted);
-
Span pixelRow = pixels.GetRowSpan(newY);
int offset = 0;
for (int x = 0; x < width; x++)
{
- short temp = BitConverter.ToInt16(row.Bytes, offset);
+ short temp = BitConverter.ToInt16(buffer.Array, offset);
- rgba.R = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR);
- rgba.G = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG);
- rgba.B = (byte)((temp & Rgb16BMask) * ScaleR);
+ rgba.R = GetBytesFrom5BitValue((temp & Rgb16RMask) >> 10);
+ rgba.G = GetBytesFrom5BitValue((temp & Rgb16GMask) >> 5);
+ rgba.B = GetBytesFrom5BitValue(temp & Rgb16BMask);
color.PackFromRgba32(rgba);
pixelRow[x] = color;
- offset += ComponentCount;
+ offset += 2;
}
}
}
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 8be892233..9137049ee 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -140,8 +140,10 @@ namespace SixLabors.ImageSharp.Tests
public const string RLEInverted = "Bmp/RunLengthEncoded-inverted.bmp";
public const string Bit8 = "Bmp/test8.bmp";
public const string Bit8Inverted = "Bmp/test8-inverted.bmp";
+ public const string Bit16 = "Bmp/test16.bmp";
+ public const string Bit16Inverted = "Bmp/test16-inverted.bmp";
- public static readonly string[] All = { Car, F, NegHeight, CoreHeader, V5Header, RLE, RLEInverted, Bit8, Bit8Inverted };
+ public static readonly string[] All = { Car, F, NegHeight, CoreHeader, V5Header, RLE, RLEInverted, Bit8, Bit8Inverted, Bit16, Bit16Inverted };
}
public static class Gif
diff --git a/tests/Images/Input/Bmp/test16-inverted.bmp b/tests/Images/Input/Bmp/test16-inverted.bmp
new file mode 100644
index 000000000..551de69b3
--- /dev/null
+++ b/tests/Images/Input/Bmp/test16-inverted.bmp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:474f93277f764b75ec91446fdffb8f290a6073236aed468a65cba5a333707c7d
+size 16438
diff --git a/tests/Images/Input/Bmp/test16.bmp b/tests/Images/Input/Bmp/test16.bmp
new file mode 100644
index 000000000..d6c5a67a6
--- /dev/null
+++ b/tests/Images/Input/Bmp/test16.bmp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:472193f2506d768c45ec167518cb7da56e0e8707887431db20d1cfa5f61bd235
+size 16438