Skip to content

Commit

Permalink
More efficient interop for BITMAPINFOHEADER (#33967)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotas authored Mar 23, 2020
1 parent 14516b6 commit 2b55fe5
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private BufferedGraphics AllocBuffer(Graphics? targetGraphics, IntPtr targetDC,
/// table or bitmasks, as appropriate.
/// </summary>
/// <returns>True if successful, false otherwise.</returns>
private bool FillBitmapInfo(IntPtr hdc, IntPtr hpal, ref NativeMethods.BITMAPINFO_FLAT pbmi)
private unsafe bool FillBitmapInfo(IntPtr hdc, IntPtr hpal, ref NativeMethods.BITMAPINFO_FLAT pbmi)
{
IntPtr hbm = IntPtr.Zero;
bool bRet = false;
Expand All @@ -104,8 +104,7 @@ private bool FillBitmapInfo(IntPtr hdc, IntPtr hpal, ref NativeMethods.BITMAPINF
throw new OutOfMemoryException(SR.GraphicsBufferQueryFail);
}

pbmi.bmiHeader_biSize = Marshal.SizeOf(typeof(NativeMethods.BITMAPINFOHEADER));
pbmi.bmiColors = new byte[NativeMethods.BITMAPINFO_MAX_COLORSIZE * 4];
pbmi.bmiHeader_biSize = sizeof(NativeMethods.BITMAPINFOHEADER);

// Call first time to fill in BITMAPINFO header.
SafeNativeMethods.GetDIBits(new HandleRef(null, hdc),
Expand Down
16 changes: 0 additions & 16 deletions src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,22 +562,6 @@ public struct BITMAP
public IntPtr bmBits;
}

[StructLayout(LayoutKind.Sequential)]
public class BITMAPINFOHEADER
{
public int biSize = 40;
public int biWidth;
public int biHeight;
public short biPlanes;
public short biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int biClrImportant;
}

// https://devblogs.microsoft.com/oldnewthing/20101018-00/?p=12513
// https://devblogs.microsoft.com/oldnewthing/20120720-00/?p=7083

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ private void SaveBestSingleIcon(BinaryWriter writer, int width, int height)
SaveIconImage(writer, (IconImage)imageData![best]);
}

private void SaveBitmapAsIcon(BinaryWriter writer)
private unsafe void SaveBitmapAsIcon(BinaryWriter writer)
{
writer.Write((ushort)0); // idReserved must be 0
writer.Write((ushort)1); // idType must be 1
Expand All @@ -466,7 +466,7 @@ private void SaveBitmapAsIcon(BinaryWriter writer)
ide.imageOffset = 22; // 22 is the first icon position (for single icon files)

BitmapInfoHeader bih = default;
bih.biSize = (uint)Marshal.SizeOf(typeof(BitmapInfoHeader));
bih.biSize = (uint)sizeof(BitmapInfoHeader);
bih.biWidth = bitmap.Width;
bih.biHeight = 2 * bitmap.Height; // include both XOR and AND images
bih.biPlanes = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ private unsafe Bitmap BmpFrame()
uint* pixelPtr = (uint*)bmpdata.Scan0.ToPointer();

// jumping the image header
int newOffset = (int)(_bestImageOffset + Marshal.SizeOf(typeof(SafeNativeMethods.BITMAPINFOHEADER)));
int newOffset = (int)(_bestImageOffset + sizeof(NativeMethods.BITMAPINFOHEADER));
// there is no color table that we need to skip since we're 32bpp

int lineLength = Size.Width * 4;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace System.Drawing
{
internal class NativeMethods
{
internal static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
internal static HandleRef NullHandleRef => new HandleRef(null, IntPtr.Zero);

public const int MAX_PATH = 260;
internal const int SM_REMOTESESSION = 0x1000;
Expand All @@ -20,9 +20,9 @@ internal class NativeMethods
internal const int BITMAPINFO_MAX_COLORSIZE = 256;

[StructLayout(LayoutKind.Sequential)]
internal struct BITMAPINFO_FLAT
internal unsafe struct BITMAPINFO_FLAT
{
public int bmiHeader_biSize; // = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
public int bmiHeader_biSize; // = sizeof(BITMAPINFOHEADER)
public int bmiHeader_biWidth;
public int bmiHeader_biHeight;
public short bmiHeader_biPlanes;
Expand All @@ -34,14 +34,13 @@ internal struct BITMAPINFO_FLAT
public int bmiHeader_biClrUsed;
public int bmiHeader_biClrImportant;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = BITMAPINFO_MAX_COLORSIZE * 4)]
public byte[] bmiColors; // RGBQUAD structs... Blue-Green-Red-Reserved, repeat...
public fixed byte bmiColors[BITMAPINFO_MAX_COLORSIZE * 4]; // RGBQUAD structs... Blue-Green-Red-Reserved, repeat...
}

[StructLayout(LayoutKind.Sequential)]
internal class BITMAPINFOHEADER
internal struct BITMAPINFOHEADER
{
public int biSize = 40;
public int biSize;
public int biWidth;
public int biHeight;
public short biPlanes;
Expand Down

0 comments on commit 2b55fe5

Please sign in to comment.