Browse Source

Merge pull request #791 from brianpopow/feature/BmpOS22ShortSupport

WIP: Adds support for Decoding Bitmaps with 16 bytes headers
pull/801/head
James Jackson-South 7 years ago
committed by GitHub
parent
commit
4f1e6249cf
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 24
      src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs
  3. 19
      tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs
  4. 1
      tests/ImageSharp.Tests/TestImages.cs
  5. BIN
      tests/Images/Input/Bmp/pal8os2v2-16.bmp

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

@ -510,6 +510,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
// 12 bytes
this.infoHeader = BmpInfoHeader.ParseCore(buffer);
}
else if (headerSize == BmpInfoHeader.Os22ShortSize)
{
// 16 bytes
this.infoHeader = BmpInfoHeader.ParseOs22Short(buffer);
}
else if (headerSize >= BmpInfoHeader.Size)
{
// >= 40 bytes

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

@ -26,6 +26,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
public const int CoreSize = 12;
/// <summary>
/// Defines the size of the short variant of the OS22XBITMAPHEADER data structure in the bitmap file.
/// </summary>
public const int Os22ShortSize = 16;
/// <summary>
/// Defines the size of the biggest supported header data structure in the bitmap file.
/// </summary>
@ -143,7 +148,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <summary>
/// Parses the BITMAPCOREHEADER consisting of the headerSize, width, height, planes, and bitsPerPixel fields (12 bytes).
/// </summary>
/// <param name="data">The data to parse,</param>
/// <param name="data">The data to parse.</param>
/// <returns>Parsed header</returns>
/// <seealso href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd183372.aspx"/>
public static BmpInfoHeader ParseCore(ReadOnlySpan<byte> data)
@ -156,6 +161,23 @@ namespace SixLabors.ImageSharp.Formats.Bmp
bitsPerPixel: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(10, 2)));
}
/// <summary>
/// Parses a short variant of the OS22XBITMAPHEADER. It is identical to the BITMAPCOREHEADER, except that the width and height
/// are 4 bytes instead of 2.
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>Parsed header</returns>
/// <seealso href="https://www.fileformat.info/format/os2bmp/egff.htm"/>
public static BmpInfoHeader ParseOs22Short(ReadOnlySpan<byte> data)
{
return new BmpInfoHeader(
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)),
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)),
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)),
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)),
bitsPerPixel: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(14, 2)));
}
public unsafe void WriteTo(Span<byte> buffer)
{
ref BmpInfoHeader dest = ref Unsafe.As<byte, BmpInfoHeader>(ref MemoryMarshal.GetReference(buffer));

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

@ -89,18 +89,17 @@ namespace SixLabors.ImageSharp.Tests
}
[Theory]
[MemberData(nameof(RatioFiles))]
public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
[WithFile(Os2v2Short, PixelTypes.Rgba32)]
public void BmpDecoder_CanDecode_Os2v2XShortHeader<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
{
var decoder = new BmpDecoder();
IImageInfo image = decoder.Identify(Configuration.Default, stream);
ImageMetaData meta = image.MetaData;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
image.DebugSave(provider, "png");
// TODO: Neither System.Drawing not MagickReferenceDecoder
// can correctly decode this file.
// image.CompareToOriginal(provider);
}
}
}

1
tests/ImageSharp.Tests/TestImages.cs

@ -201,6 +201,7 @@ namespace SixLabors.ImageSharp.Tests
public const string Bit16 = "Bmp/test16.bmp";
public const string Bit16Inverted = "Bmp/test16-inverted.bmp";
public const string Bit32Rgb = "Bmp/rgb32.bmp";
public const string Os2v2Short = "Bmp/pal8os2v2-16.bmp";
public static readonly string[] All
= {

BIN
tests/Images/Input/Bmp/pal8os2v2-16.bmp

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Loading…
Cancel
Save