Browse Source

Fix 16bit decode and add tests

af/merge-core
James Jackson-South 8 years ago
parent
commit
f3f2e41001
  1. 43
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 4
      tests/ImageSharp.Tests/TestImages.cs
  3. 3
      tests/Images/Input/Bmp/test16-inverted.bmp
  4. 3
      tests/Images/Input/Bmp/test16.bmp

43
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -12,22 +12,25 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <summary>
/// Performs the bmp decoding operation.
/// </summary>
/// <remarks>
/// A useful decoding source example can be found at <see href="https://dxr.mozilla.org/mozilla-central/source/image/decoders/nsBMPDecoder.cpp"/>
/// </remarks>
internal sealed class BmpDecoderCore
{
/// <summary>
/// The mask for the red part of the color for 16 bit rgb bitmaps.
/// </summary>
private const int Rgb16RMask = 0x00007C00;
private const int Rgb16RMask = 0x7C00;
/// <summary>
/// The mask for the green part of the color for 16 bit rgb bitmaps.
/// </summary>
private const int Rgb16GMask = 0x000003E0;
private const int Rgb16GMask = 0x3E0;
/// <summary>
/// The mask for the blue part of the color for 16 bit rgb bitmaps.
/// </summary>
private const int Rgb16BMask = 0x0000001F;
private const int Rgb16BMask = 0x1F;
/// <summary>
/// RLE8 flag value that indicates following byte has special meaning
@ -233,6 +236,17 @@ namespace SixLabors.ImageSharp.Formats.Bmp
return padding;
}
/// <summary>
/// Performs final shifting from a 5bit value to an 8bit one.
/// </summary>
/// <param name="value">The masked and shifted value</param>
/// <returns>The <see cref="byte"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte GetBytesFrom5BitValue(int value)
{
return (byte)((value << 3) | (value >> 2));
}
/// <summary>
/// Looks up color values and builds the image from de-compressed RLE8 data.
/// Compresssed RLE8 stream is uncompressed by <see cref="UncompressRle8(int, Span{byte})"/>
@ -416,36 +430,31 @@ namespace SixLabors.ImageSharp.Formats.Bmp
private void ReadRgb16<TPixel>(PixelAccessor<TPixel> pixels, int width, int height, bool inverted)
where TPixel : struct, IPixel<TPixel>
{
// 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<TPixel>(width, ComponentOrder.Xyz))
using (var buffer = new Buffer<byte>(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<TPixel> 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;
}
}
}

4
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

3
tests/Images/Input/Bmp/test16-inverted.bmp

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:474f93277f764b75ec91446fdffb8f290a6073236aed468a65cba5a333707c7d
size 16438

3
tests/Images/Input/Bmp/test16.bmp

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:472193f2506d768c45ec167518cb7da56e0e8707887431db20d1cfa5f61bd235
size 16438
Loading…
Cancel
Save