Browse Source

Merge remote-tracking branch 'origin/master' into beta-1

# Conflicts:
#	src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
af/merge-core
Anton Firszov 9 years ago
parent
commit
165152bf44
  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. 27
      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

@ -1,5 +1,6 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -133,11 +134,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp
switch (this.infoHeader.Compression) switch (this.infoHeader.Compression)
{ {
case BmpCompression.RGB: 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) if (this.infoHeader.BitsPerPixel == 32)
{ {
this.ReadRgb32(pixels, this.infoHeader.Width, this.infoHeader.Height, inverted); this.ReadRgb32(pixels, this.infoHeader.Width, this.infoHeader.Height, inverted);
@ -372,11 +368,69 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary> /// </summary>
private void ReadInfoHeader() 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), HeaderSize = BitConverter.ToInt32(data, 0),
Width = BitConverter.ToInt32(data, 4), Width = BitConverter.ToInt32(data, 4),

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

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

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

@ -11,12 +11,27 @@ namespace SixLabors.ImageSharp.Formats.Bmp
internal sealed class BmpInfoHeader internal sealed class BmpInfoHeader
{ {
/// <summary> /// <summary>
/// Defines of the data structure in the bitmap file. /// Defines the size of the BITMAPINFOHEADER data structure in the bitmap file.
/// </summary> /// </summary>
public const int Size = 40; public const int BitmapInfoHeaderSize = 40;
/// <summary> /// <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> /// </summary>
public int HeaderSize { get; set; } public int HeaderSize { get; set; }

1
tests/ImageSharp.Tests/FileTestBase.cs

@ -83,6 +83,7 @@ namespace SixLabors.ImageSharp.Tests
// TestFile.Create(TestImages.Jpeg.Progressive.Bad.BadEOF), // Perf: Enable for local testing only // TestFile.Create(TestImages.Jpeg.Progressive.Bad.BadEOF), // Perf: Enable for local testing only
TestFile.Create(TestImages.Bmp.Car), TestFile.Create(TestImages.Bmp.Car),
// TestFile.Create(TestImages.Bmp.NegHeight), // Perf: Enable for local testing only // 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.Splash),
// TestFile.Create(TestImages.Png.Cross), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Cross), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Bad.ChunkLength1), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Bad.ChunkLength1), // Perf: Enable for local testing only

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

@ -0,0 +1,27 @@
// <copyright file="BmpEncoderTests.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using ImageSharp.Formats;
namespace ImageSharp.Tests
{
using ImageSharp.PixelFormats;
using Xunit;
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");
}
}
}
}

3
tests/ImageSharp.Tests/TestImages.cs

@ -119,7 +119,8 @@ namespace SixLabors.ImageSharp.Tests
public const string Car = "Bmp/Car.bmp"; public const string Car = "Bmp/Car.bmp";
public const string F = "Bmp/F.bmp"; public const string F = "Bmp/F.bmp";
public const string NegHeight = "Bmp/neg_height.bmp"; public const string NegHeight = "Bmp/neg_height.bmp";
public static readonly string[] All = { Car, F, NegHeight }; public const string CoreHeader = "Bmp/BitmapCoreHeaderQR.bmp";
public static readonly string[] All = { Car, F, NegHeight, CoreHeader };
} }
public static class Gif 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