Browse Source

sync with upstream

af/merge-core
Nikita Balabaev 9 years ago
parent
commit
4e997a4089
  1. 70
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 2
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  3. 21
      src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs
  4. 1
      tests/ImageSharp.Tests/FileTestBase.cs
  5. 22
      tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs
  6. 3
      tests/ImageSharp.Tests/TestImages.cs
  7. 3
      tests/ImageSharp.Tests/TestImages/Formats/Bmp/BitmapCoreHeaderQR.bmp

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

@ -2,6 +2,7 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Formats
{
using System;
@ -135,11 +136,6 @@ namespace ImageSharp.Formats
switch (this.infoHeader.Compression)
{
case BmpCompression.RGB:
if (this.infoHeader.HeaderSize != 40)
{
throw new ImageFormatException($"Header Size value '{this.infoHeader.HeaderSize}' is not valid.");
}
if (this.infoHeader.BitsPerPixel == 32)
{
this.ReadRgb32(pixels, this.infoHeader.Width, this.infoHeader.Height, inverted);
@ -374,11 +370,69 @@ namespace ImageSharp.Formats
/// </summary>
private void ReadInfoHeader()
{
byte[] data = new byte[BmpInfoHeader.Size];
byte[] data = new byte[BmpInfoHeader.MaxHeaderSize];
// read header size
this.currentStream.Read(data, 0, BmpInfoHeader.HeaderSizeSize);
int headerSize = BitConverter.ToInt32(data, 0);
if (headerSize < BmpInfoHeader.HeaderSizeSize || headerSize > BmpInfoHeader.MaxHeaderSize)
{
throw new NotSupportedException($"This kind of bitmap files (header size $headerSize) is not supported.");
}
// read the rest of the header
this.currentStream.Read(data, BmpInfoHeader.HeaderSizeSize, headerSize - BmpInfoHeader.HeaderSizeSize);
switch (headerSize)
{
case BmpInfoHeader.BitmapCoreHeaderSize:
this.infoHeader = this.ParseBitmapCoreHeader(data);
break;
case BmpInfoHeader.BitmapInfoHeaderSize:
this.infoHeader = this.ParseBitmapInfoHeader(data);
break;
default:
throw new NotSupportedException($"This kind of bitmap files (header size $headerSize) is not supported.");
}
}
this.currentStream.Read(data, 0, BmpInfoHeader.Size);
/// <summary>
/// Parses the <see cref="BmpInfoHeader"/> from the stream, assuming it uses the BITMAPCOREHEADER format.
/// </summary>
/// <param name="data">Header bytes read from the stream</param>
/// <returns>Parsed header</returns>
/// <seealso href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd183372.aspx"/>
private BmpInfoHeader ParseBitmapCoreHeader(byte[] data)
{
return new BmpInfoHeader
{
HeaderSize = BitConverter.ToInt32(data, 0),
Width = BitConverter.ToUInt16(data, 4),
Height = BitConverter.ToUInt16(data, 6),
Planes = BitConverter.ToInt16(data, 8),
BitsPerPixel = BitConverter.ToInt16(data, 10),
// the rest is not present in the core header
ImageSize = 0,
XPelsPerMeter = 0,
YPelsPerMeter = 0,
ClrUsed = 0,
ClrImportant = 0,
Compression = BmpCompression.RGB
};
}
this.infoHeader = new BmpInfoHeader
/// <summary>
/// Parses the <see cref="BmpInfoHeader"/> from the stream, assuming it uses the BITMAPINFOHEADER format.
/// </summary>
/// <param name="data">Header bytes read from the stream</param>
/// <returns>Parsed header</returns>
/// <seealso href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx"/>
private BmpInfoHeader ParseBitmapInfoHeader(byte[] data)
{
return new BmpInfoHeader
{
HeaderSize = BitConverter.ToInt32(data, 0),
Width = BitConverter.ToInt32(data, 4),

2
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -58,7 +58,7 @@ namespace ImageSharp.Formats
BmpInfoHeader infoHeader = new BmpInfoHeader
{
HeaderSize = BmpInfoHeader.Size,
HeaderSize = BmpInfoHeader.BitmapInfoHeaderSize,
Height = image.Height,
Width = image.Width,
BitsPerPixel = bpp,

21
src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs

@ -13,12 +13,27 @@ namespace ImageSharp.Formats
internal sealed class BmpInfoHeader
{
/// <summary>
/// Defines of the data structure in the bitmap file.
/// Defines the size of the BITMAPINFOHEADER data structure in the bitmap file.
/// </summary>
public const int Size = 40;
public const int BitmapInfoHeaderSize = 40;
/// <summary>
/// Gets or sets the size of this header (40 bytes)
/// Defines the size of the BITMAPCOREHEADER data structure in the bitmap file.
/// </summary>
public const int BitmapCoreHeaderSize = 12;
/// <summary>
/// Defines the size of the biggest supported header data structure in the bitmap file.
/// </summary>
public const int MaxHeaderSize = BitmapInfoHeaderSize;
/// <summary>
/// Defines the size of the <see cref="HeaderSize"/> field.
/// </summary>
public const int HeaderSizeSize = 4;
/// <summary>
/// Gets or sets the size of this header
/// </summary>
public int HeaderSize { get; set; }

1
tests/ImageSharp.Tests/FileTestBase.cs

@ -77,6 +77,7 @@ namespace ImageSharp.Tests
// TestFile.Create(TestImages.Jpeg.Progressive.Bad.BadEOF), // Perf: Enable for local testing only
TestFile.Create(TestImages.Bmp.Car),
// TestFile.Create(TestImages.Bmp.NegHeight), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Bmp.CoreHeader), // Perf: Enable for local testing only
TestFile.Create(TestImages.Png.Splash),
// TestFile.Create(TestImages.Png.Cross), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Bad.ChunkLength1), // Perf: Enable for local testing only

22
tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs

@ -1,17 +1,29 @@
// <copyright file="GifDecoderTests.cs" company="James Jackson-South">
// <copyright file="BmpDecoderTests.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// ReSharper disable InconsistentNaming
using ImageSharp.Formats;
namespace ImageSharp.Tests
{
using System.IO;
using ImageSharp.PixelFormats;
using Xunit;
public class BmpDecoderTests
public class BmpDecoderTests : FileTestBase
{
[Theory]
[WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgb24)]
public void OpenAllBmpFiles_SaveBmp<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
provider.Utility.SaveTestOutputFile(image, "bmp");
}
}
[Theory]
[InlineData(TestImages.Bmp.Car, 24)]
[InlineData(TestImages.Bmp.F, 24)]
@ -26,4 +38,4 @@ namespace ImageSharp.Tests
}
}
}
}
}

3
tests/ImageSharp.Tests/TestImages.cs

@ -120,7 +120,8 @@ namespace ImageSharp.Tests
public const string F = "Bmp/F.bmp";
public const string Bpp8 = "Bmp/bpp8.bmp";
public const string NegHeight = "Bmp/neg_height.bmp";
public static readonly string[] All = { Car, F, NegHeight, Bpp8 };
public const string CoreHeader = "Bmp/BitmapCoreHeaderQR.bmp";
public static readonly string[] All = { Car, F, NegHeight, CoreHeader, Bpp8 };
}
public static class Gif

3
tests/ImageSharp.Tests/TestImages/Formats/Bmp/BitmapCoreHeaderQR.bmp

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