Browse Source

Merge pull request #393 from Greenliff/feature/bmp-neg-height

#392 add support for negative height in bmp files

Former-commit-id: ae5a785823ff084974143114b2776346240b4e1d
Former-commit-id: 97b8838371e1ee37ce13258ad9d74f8a99e9cf09
Former-commit-id: 594abd7144968200df9b03bc50ab98cef770a313
pull/1/head
James Jackson-South 10 years ago
parent
commit
d9fa43cb28
  1. 41
      src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs
  2. 1
      tests/ImageProcessorCore.Tests/FileTestBase.cs
  3. 1
      tests/ImageProcessorCore.Tests/TestImages/Formats/Bmp/neg_height.bmp.REMOVED.git-id

41
src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs

@ -67,6 +67,18 @@ namespace ImageProcessorCore.Formats
this.ReadFileHeader();
this.ReadInfoHeader();
// see http://www.drdobbs.com/architecture-and-design/the-bmp-file-format-part-1/184409517
// If the height is negative, then this is a Windows bitmap whose origin
// is the upper-left corner and not the lower-left.The inverted flag
// indicates a lower-left origin.Our code will be outputting an
// upper-left origin pixel array.
bool inverted = false;
if (this.infoHeader.Height < 0)
{
inverted = true;
this.infoHeader.Height = -this.infoHeader.Height;
}
int colorMapSize = -1;
if (this.infoHeader.ClrUsed == 0)
@ -118,15 +130,15 @@ namespace ImageProcessorCore.Formats
if (this.infoHeader.BitsPerPixel == 32)
{
this.ReadRgb32(imageData, this.infoHeader.Width, this.infoHeader.Height);
this.ReadRgb32(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
}
else if (this.infoHeader.BitsPerPixel == 24)
{
this.ReadRgb24(imageData, this.infoHeader.Width, this.infoHeader.Height);
this.ReadRgb24(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
}
else if (this.infoHeader.BitsPerPixel == 16)
{
this.ReadRgb16(imageData, this.infoHeader.Width, this.infoHeader.Height);
this.ReadRgb16(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
}
else if (this.infoHeader.BitsPerPixel <= 8)
{
@ -135,7 +147,8 @@ namespace ImageProcessorCore.Formats
palette,
this.infoHeader.Width,
this.infoHeader.Height,
this.infoHeader.BitsPerPixel);
this.infoHeader.BitsPerPixel,
inverted);
}
break;
@ -157,11 +170,11 @@ namespace ImageProcessorCore.Formats
/// <param name="y">The y- value representing the current row.</param>
/// <param name="height">The height of the bitmap.</param>
/// <returns>The <see cref="int"/> representing the inverted value.</returns>
private static int Invert(int y, int height)
private static int Invert(int y, int height, bool inverted)
{
int row;
if (height > 0)
if (!inverted)
{
row = height - y - 1;
}
@ -181,7 +194,7 @@ namespace ImageProcessorCore.Formats
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <param name="bits">The number of bits per pixel.</param>
private void ReadRgbPalette(float[] imageData, byte[] colors, int width, int height, int bits)
private void ReadRgbPalette(float[] imageData, byte[] colors, int width, int height, int bits, bool inverted)
{
// Pixels per byte (bits per pixel)
int ppb = 8 / bits;
@ -214,7 +227,7 @@ namespace ImageProcessorCore.Formats
int offset = rowOffset + x;
// Revert the y value, because bitmaps are saved from down to top
int row = Invert(y, height);
int row = Invert(y, height, inverted);
int colOffset = x * ppb;
@ -240,7 +253,7 @@ namespace ImageProcessorCore.Formats
/// <param name="imageData">The <see cref="T:float[]"/> image data to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
private void ReadRgb16(float[] imageData, int width, int height)
private void ReadRgb16(float[] imageData, int width, int height, bool inverted)
{
// We divide here as we will store the colors in our floating point format.
const float ScaleR = 0.25F; // (256 / 32) / 32
@ -257,7 +270,7 @@ namespace ImageProcessorCore.Formats
int rowOffset = y * ((width * 2) + alignment);
// Revert the y value, because bitmaps are saved from down to top
int row = Invert(y, height);
int row = Invert(y, height, inverted);
for (int x = 0; x < width; x++)
{
@ -286,7 +299,7 @@ namespace ImageProcessorCore.Formats
/// <param name="imageData">The <see cref="T:float[]"/> image data to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
private void ReadRgb24(float[] imageData, int width, int height)
private void ReadRgb24(float[] imageData, int width, int height, bool inverted)
{
int alignment;
byte[] data = this.GetImageArray(width, height, 3, out alignment);
@ -299,7 +312,7 @@ namespace ImageProcessorCore.Formats
int rowOffset = y * ((width * 3) + alignment);
// Revert the y value, because bitmaps are saved from down to top
int row = Invert(y, height);
int row = Invert(y, height, inverted);
for (int x = 0; x < width; x++)
{
@ -322,7 +335,7 @@ namespace ImageProcessorCore.Formats
/// <param name="imageData">The <see cref="T:float[]"/> image data to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
private void ReadRgb32(float[] imageData, int width, int height)
private void ReadRgb32(float[] imageData, int width, int height, bool inverted)
{
int alignment;
byte[] data = this.GetImageArray(width, height, 4, out alignment);
@ -335,7 +348,7 @@ namespace ImageProcessorCore.Formats
int rowOffset = y * ((width * 4) + alignment);
// Revert the y value, because bitmaps are saved from down to top
int row = Invert(y, height);
int row = Invert(y, height, inverted);
for (int x = 0; x < width; x++)
{

1
tests/ImageProcessorCore.Tests/FileTestBase.cs

@ -25,6 +25,7 @@ namespace ImageProcessorCore.Tests
//"TestImages/Formats/Jpg/progress.jpg", // Perf: Enable for local testing only
//"TestImages/Formats/Jpg/gamma_dalai_lama_gray.jpg", // Perf: Enable for local testing only
"TestImages/Formats/Bmp/Car.bmp",
// "TestImages/Formats/Bmp/neg_height.bmp", // Perf: Enable for local testing only
//"TestImages/Formats/Png/blur.png", // Perf: Enable for local testing only
//"TestImages/Formats/Png/indexed.png", // Perf: Enable for local testing only
"TestImages/Formats/Png/splash.png",

1
tests/ImageProcessorCore.Tests/TestImages/Formats/Bmp/neg_height.bmp.REMOVED.git-id

@ -0,0 +1 @@
8f864b82464c595d7a81087d018db9994506e221
Loading…
Cancel
Save