|
|
|
@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
int greenMask = 0, |
|
|
|
int blueMask = 0, |
|
|
|
int alphaMask = 0, |
|
|
|
int csType = 0, |
|
|
|
BmpColorSpace csType = 0, |
|
|
|
int redX = 0, |
|
|
|
int redY = 0, |
|
|
|
int redZ = 0, |
|
|
|
@ -94,7 +94,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
int blueZ = 0, |
|
|
|
int gammeRed = 0, |
|
|
|
int gammeGreen = 0, |
|
|
|
int gammeBlue = 0) |
|
|
|
int gammeBlue = 0, |
|
|
|
BmpRenderingIntent intent = BmpRenderingIntent.Invalid, |
|
|
|
int profileData = 0, |
|
|
|
int profileSize = 0, |
|
|
|
int reserved = 0) |
|
|
|
{ |
|
|
|
this.HeaderSize = headerSize; |
|
|
|
this.Width = width; |
|
|
|
@ -124,6 +128,10 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
this.GammaRed = gammeRed; |
|
|
|
this.GammaGreen = gammeGreen; |
|
|
|
this.GammaBlue = gammeBlue; |
|
|
|
this.Intent = intent; |
|
|
|
this.ProfileData = profileData; |
|
|
|
this.ProfileSize = profileSize; |
|
|
|
this.Reserved = reserved; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -211,7 +219,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the Color space type. Not used yet.
|
|
|
|
/// </summary>
|
|
|
|
public int CsType { get; set; } |
|
|
|
public BmpColorSpace CsType { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the X coordinate of red endpoint. Not used yet.
|
|
|
|
@ -273,21 +281,38 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// </summary>
|
|
|
|
public int GammaBlue { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the rendering intent for bitmap.
|
|
|
|
/// </summary>
|
|
|
|
public BmpRenderingIntent Intent { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the offset, in bytes, from the beginning of the BITMAPV5HEADER structure to the start of the profile data.
|
|
|
|
/// </summary>
|
|
|
|
public int ProfileData { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the size, in bytes, of embedded profile data.
|
|
|
|
/// </summary>
|
|
|
|
public int ProfileSize { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the reserved value.
|
|
|
|
/// </summary>
|
|
|
|
public int Reserved { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Parses the BITMAPCOREHEADER (BMP Version 2) consisting of the headerSize, width, height, planes, and bitsPerPixel fields (12 bytes).
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">The data to parse.</param>
|
|
|
|
/// <returns>The parsed header.</returns>
|
|
|
|
/// <seealso href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd183372.aspx"/>
|
|
|
|
public static BmpInfoHeader ParseCore(ReadOnlySpan<byte> data) |
|
|
|
{ |
|
|
|
return new BmpInfoHeader( |
|
|
|
public static BmpInfoHeader ParseCore(ReadOnlySpan<byte> data) => new( |
|
|
|
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), |
|
|
|
width: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(4, 2)), |
|
|
|
height: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(6, 2)), |
|
|
|
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(8, 2)), |
|
|
|
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
|
|
|
|
@ -296,15 +321,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// <param name="data">The data to parse.</param>
|
|
|
|
/// <returns>The parsed header.</returns>
|
|
|
|
/// <seealso href="https://www.fileformat.info/format/os2bmp/egff.htm"/>
|
|
|
|
public static BmpInfoHeader ParseOs22Short(ReadOnlySpan<byte> data) |
|
|
|
{ |
|
|
|
return new BmpInfoHeader( |
|
|
|
public static BmpInfoHeader ParseOs22Short(ReadOnlySpan<byte> data) => new( |
|
|
|
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))); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Parses the full BMP Version 3 BITMAPINFOHEADER header (40 bytes).
|
|
|
|
@ -312,9 +334,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// <param name="data">The data to parse.</param>
|
|
|
|
/// <returns>The parsed header.</returns>
|
|
|
|
/// <seealso href="http://www.fileformat.info/format/bmp/egff.htm"/>
|
|
|
|
public static BmpInfoHeader ParseV3(ReadOnlySpan<byte> data) |
|
|
|
{ |
|
|
|
return new BmpInfoHeader( |
|
|
|
public static BmpInfoHeader ParseV3(ReadOnlySpan<byte> data) => new( |
|
|
|
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), |
|
|
|
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), |
|
|
|
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), |
|
|
|
@ -326,7 +346,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
yPelsPerMeter: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(28, 4)), |
|
|
|
clrUsed: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(32, 4)), |
|
|
|
clrImportant: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(36, 4))); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Special case of the BITMAPINFOHEADER V3 used by adobe where the color bitmasks are part of the info header instead of following it.
|
|
|
|
@ -336,9 +355,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// <param name="withAlpha">Indicates, if the alpha bitmask is present.</param>
|
|
|
|
/// <returns>The parsed header.</returns>
|
|
|
|
/// <seealso href="https://forums.adobe.com/message/3272950#3272950"/>
|
|
|
|
public static BmpInfoHeader ParseAdobeV3(ReadOnlySpan<byte> data, bool withAlpha = true) |
|
|
|
{ |
|
|
|
return new BmpInfoHeader( |
|
|
|
public static BmpInfoHeader ParseAdobeV3(ReadOnlySpan<byte> data, bool withAlpha = true) => new( |
|
|
|
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), |
|
|
|
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), |
|
|
|
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), |
|
|
|
@ -354,7 +371,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
greenMask: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(44, 4)), |
|
|
|
blueMask: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(48, 4)), |
|
|
|
alphaMask: withAlpha ? BinaryPrimitives.ReadInt32LittleEndian(data.Slice(52, 4)) : 0); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Parses a OS/2 version 2 bitmap header (64 bytes). Only the first 40 bytes are parsed which are
|
|
|
|
@ -413,11 +429,47 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// <param name="data">The data to parse.</param>
|
|
|
|
/// <returns>The parsed header.</returns>
|
|
|
|
/// <seealso href="http://www.fileformat.info/format/bmp/egff.htm"/>
|
|
|
|
public static BmpInfoHeader ParseV4(ReadOnlySpan<byte> data) |
|
|
|
public static BmpInfoHeader ParseV4(ReadOnlySpan<byte> data) => new( |
|
|
|
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)), |
|
|
|
compression: (BmpCompression)BinaryPrimitives.ReadInt32LittleEndian(data.Slice(16, 4)), |
|
|
|
imageSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(20, 4)), |
|
|
|
xPelsPerMeter: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(24, 4)), |
|
|
|
yPelsPerMeter: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(28, 4)), |
|
|
|
clrUsed: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(32, 4)), |
|
|
|
clrImportant: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(36, 4)), |
|
|
|
redMask: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(40, 4)), |
|
|
|
greenMask: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(44, 4)), |
|
|
|
blueMask: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(48, 4)), |
|
|
|
alphaMask: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(52, 4)), |
|
|
|
csType: (BmpColorSpace)BinaryPrimitives.ReadInt32LittleEndian(data.Slice(56, 4)), |
|
|
|
redX: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(60, 4)), |
|
|
|
redY: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(64, 4)), |
|
|
|
redZ: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(68, 4)), |
|
|
|
greenX: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(72, 4)), |
|
|
|
greenY: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(76, 4)), |
|
|
|
greenZ: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(80, 4)), |
|
|
|
blueX: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(84, 4)), |
|
|
|
blueY: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(88, 4)), |
|
|
|
blueZ: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(92, 4)), |
|
|
|
gammeRed: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(96, 4)), |
|
|
|
gammeGreen: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(100, 4)), |
|
|
|
gammeBlue: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(104, 4))); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Parses the full BMP Version 5 BITMAPINFOHEADER header (124 bytes).
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">The data to parse.</param>
|
|
|
|
/// <returns>The parsed header.</returns>
|
|
|
|
/// <seealso href="https://docs.microsoft.com/de-de/windows/win32/api/wingdi/ns-wingdi-bitmapv5header?redirectedfrom=MSDN"/>
|
|
|
|
public static BmpInfoHeader ParseV5(ReadOnlySpan<byte> data) |
|
|
|
{ |
|
|
|
if (data.Length < SizeV4) |
|
|
|
if (data.Length < SizeV5) |
|
|
|
{ |
|
|
|
throw new ArgumentException(nameof(data), $"Must be {SizeV4} bytes. Was {data.Length} bytes."); |
|
|
|
throw new ArgumentException(nameof(data), $"Must be {SizeV5} bytes. Was {data.Length} bytes."); |
|
|
|
} |
|
|
|
|
|
|
|
return MemoryMarshal.Cast<byte, BmpInfoHeader>(data)[0]; |
|
|
|
|