Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
25e4ede
decoding bitmaps with Bitfields masks
brianpopow Dec 22, 2018
8d44e6a
added testcases for Bitfields bitmaps
brianpopow Dec 22, 2018
da6c23e
added parsing of the complete bitmap V4 header to get the color masks…
brianpopow Dec 22, 2018
04f1a31
writing now explicitly a Bitamp v3 header (40 bytes)
brianpopow Dec 22, 2018
d906395
added test image for issue #735
brianpopow Dec 22, 2018
0ef0cc8
fixed rescaling 5-bit / 6-bit to 0 - 255 range
brianpopow Dec 23, 2018
f3f3ffb
BitmapEncoder now writes BMP v4 header
brianpopow Dec 23, 2018
e415f64
using MemoryMarshal.Cast to simplify parsing v4 header
brianpopow Dec 24, 2018
791cdd8
added testcases for bitmap v3, v4, v5
brianpopow Dec 24, 2018
02d2ccd
Bitmap encoder writes again V3 header instead of V4. Additional field…
brianpopow Dec 24, 2018
d2f0848
added parsing of special case for 56 bytes headers
brianpopow Dec 26, 2018
46f0c0c
using the alpha mask in ReadRgb32BitFields() when its present
brianpopow Dec 26, 2018
746b3e3
added support for bitmasks greater then 8 bits per channel
brianpopow Dec 27, 2018
c613dbd
using MagickReferenceDecoder reference decoder for the test with 10 b…
brianpopow Dec 27, 2018
2cb5a44
changed bitmap constants to hex
brianpopow Dec 29, 2018
2ab733d
added enum for the bitmap info header type
brianpopow Dec 29, 2018
d91f736
added support for 52 bytes header (same as 56 bytes without the alpha…
brianpopow Dec 30, 2018
ba29af6
Merge branch 'master' into feature/BmpBitfields
brianpopow Dec 30, 2018
31073d4
clarified comment with difference between imagesharp and magick decod…
brianpopow Jan 7, 2019
d52d028
Merge branch 'master' into feature/BmpBitfields
brianpopow Jan 7, 2019
d6649c9
BmpEncoder now writes a V4 info header and uses BITFIELDS compression
brianpopow Jan 8, 2019
6210abe
workaround for issue that the decoder does not decode the alpha chann…
brianpopow Jan 10, 2019
6d00cf6
Merge branch 'master' into feature/BmpBitfields
brianpopow Jan 10, 2019
d6b8cd3
Fix #732
JimBobSquarePants Jan 18, 2019
f0f658e
Merge branch 'master' into feature/BmpBitfields
JimBobSquarePants Jan 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/ImageSharp/Formats/Bmp/BmpCompression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ internal enum BmpCompression : int
/// If the first byte is zero, the record has different meanings, depending
/// on the second byte. If the second byte is zero, it is the end of the row,
/// if it is one, it is the end of the image.
/// Not supported at the moment.
/// </summary>
RLE8 = 1,

Expand All @@ -42,7 +41,6 @@ internal enum BmpCompression : int
/// <summary>
/// Each image row has a multiple of four elements. If the
/// row has less elements, zeros will be added at the right side.
/// Not supported at the moment.
/// </summary>
BitFields = 3,

Expand Down
36 changes: 36 additions & 0 deletions src/ImageSharp/Formats/Bmp/BmpConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,41 @@ internal static class BmpConstants
/// The list of file extensions that equate to a bmp.
/// </summary>
public static readonly IEnumerable<string> FileExtensions = new[] { "bm", "bmp", "dip" };

/// <summary>
/// Valid magic bytes markers identifying a Bitmap file.
/// </summary>
internal static class TypeMarkers
{
/// <summary>
/// Single-image BMP file that may have been created under Windows or OS/2.
/// </summary>
public const int Bitmap = 0x4D42;

/// <summary>
/// OS/2 Bitmap Array.
/// </summary>
public const int BitmapArray = 0x4142;

/// <summary>
/// OS/2 Color Icon.
/// </summary>
public const int ColorIcon = 0x4943;

/// <summary>
/// OS/2 Color Pointer.
/// </summary>
public const int ColorPointer = 0x5043;

/// <summary>
/// OS/2 Icon.
/// </summary>
public const int Icon = 0x4349;

/// <summary>
/// OS/2 Pointer.
/// </summary>
public const int Pointer = 0x5450;
}
}
}
2 changes: 0 additions & 2 deletions src/ImageSharp/Formats/Bmp/BmpDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <item>JPG</item>
/// <item>PNG</item>
/// <item>RLE4</item>
/// <item>RLE8</item>
/// <item>BitFields</item>
/// </list>
/// Formats will be supported in a later releases. We advise always
/// to use only 24 Bit Windows bitmaps.
Expand Down
399 changes: 366 additions & 33 deletions src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

Large diffs are not rendered by default.

50 changes: 41 additions & 9 deletions src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@ internal sealed class BmpEncoderCore
/// </summary>
private int padding;

/// <summary>
/// The mask for the alpha channel of the color for a 32 bit rgba bitmaps.
/// </summary>
private const int Rgba32AlphaMask = 0xFF << 24;

/// <summary>
/// The mask for the red part of the color for a 32 bit rgba bitmaps.
/// </summary>
private const int Rgba32RedMask = 0xFF << 16;

/// <summary>
/// The mask for the green part of the color for a 32 bit rgba bitmaps.
/// </summary>
private const int Rgba32GreenMask = 0xFF << 8;

/// <summary>
/// The mask for the blue part of the color for a 32 bit rgba bitmaps.
/// </summary>
private const int Rgba32BlueMask = 0xFF;

private readonly MemoryAllocator memoryAllocator;

private Configuration configuration;
Expand Down Expand Up @@ -92,8 +112,9 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream)
}
}

int infoHeaderSize = BmpInfoHeader.SizeV4;
var infoHeader = new BmpInfoHeader(
headerSize: BmpInfoHeader.Size,
headerSize: infoHeaderSize,
height: image.Height,
width: image.Width,
bitsPerPixel: bpp,
Expand All @@ -102,26 +123,37 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream)
clrUsed: 0,
clrImportant: 0,
xPelsPerMeter: hResolution,
yPelsPerMeter: vResolution);
yPelsPerMeter: vResolution)
{
RedMask = Rgba32RedMask,
GreenMask = Rgba32GreenMask,
BlueMask = Rgba32BlueMask,
Compression = BmpCompression.BitFields
};

if (this.bitsPerPixel == BmpBitsPerPixel.Pixel32)
{
infoHeader.AlphaMask = Rgba32AlphaMask;
}

var fileHeader = new BmpFileHeader(
type: 19778, // BM
fileSize: 54 + infoHeader.ImageSize,
type: BmpConstants.TypeMarkers.Bitmap,
fileSize: BmpFileHeader.Size + infoHeaderSize + infoHeader.ImageSize,
reserved: 0,
offset: 54);
offset: BmpFileHeader.Size + infoHeaderSize);

#if NETCOREAPP2_1
Span<byte> buffer = stackalloc byte[40];
Span<byte> buffer = stackalloc byte[infoHeaderSize];
#else
byte[] buffer = new byte[40];
byte[] buffer = new byte[infoHeaderSize];
#endif
fileHeader.WriteTo(buffer);

stream.Write(buffer, 0, BmpFileHeader.Size);

infoHeader.WriteTo(buffer);
infoHeader.WriteV4Header(buffer);

stream.Write(buffer, 0, 40);
stream.Write(buffer, 0, infoHeaderSize);

this.WriteImage(stream, image.Frames.RootFrame);

Expand Down
Loading