Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More efficient interop for BITMAPINFOHEADER #33967

Merged
merged 2 commits into from
Mar 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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...
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
}

[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