|
|
|
@ -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), |
|
|
|
|