MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey-v1.0 / getbits

Function getbits

Source/script2.cpp:4053–4122  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4051
4052
4053LPCOLORREF getbits(HBITMAP ahImage, HDC hdc, LONG &aWidth, LONG &aHeight, bool &aIs16Bit)
4054// Helper function used by PixelSearch below.
4055// Returns an array of pixels to the caller, which it must free when done. Returns NULL on failure,
4056// in which case the contents of the output parameters is indeterminate.
4057{
4058 HDC tdc = CreateCompatibleDC(hdc);
4059 if (!tdc)
4060 return NULL;
4061
4062 // From this point on, "goto end" will assume tdc is non-NULL, but that the below
4063 // might still be NULL. Therefore, all of the following must be initialized so that the "end"
4064 // label can detect them:
4065 HGDIOBJ tdc_orig_select = NULL;
4066 LPCOLORREF image_pixel = NULL;
4067 bool success = false;
4068
4069 // Confirmed:
4070 // Needs extra memory to prevent buffer overflow due to: "A bottom-up DIB is specified by setting
4071 // the height to a positive number, while a top-down DIB is specified by setting the height to a
4072 // negative number. THE BITMAP COLOR TABLE WILL BE APPENDED to the BITMAPINFO structure."
4073 // Maybe this applies only to negative height, in which case the second call to GetDIBits()
4074 // below uses one.
4075 struct BITMAPINFO3
4076 {
4077 BITMAPINFOHEADER bmiHeader;
4078 RGBQUAD bmiColors[3]; // 3 vs. 1.
4079 } bmi;
4080
4081 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4082 bmi.bmiHeader.biBitCount = 0; // i.e. "query bitmap attributes" only.
4083 if (!GetDIBits(tdc, ahImage, 0, 0, NULL, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS) || bmi.bmiHeader.biBitCount < 16) // Relies on short-circuit boolean order.
4084 goto end;
4085
4086 // Set output parameters for caller:
4087 aIs16Bit = (bmi.bmiHeader.biBitCount == 16);
4088 aWidth = bmi.bmiHeader.biWidth;
4089 aHeight = bmi.bmiHeader.biHeight;
4090
4091 size_t size = bmi.bmiHeader.biWidth * bmi.bmiHeader.biHeight;
4092 if ( !(image_pixel = new DWORD[size]) )
4093 goto end;
4094 memset(image_pixel, 0xAA, size*4);
4095
4096 bmi.bmiHeader.biBitCount = 32;
4097 bmi.bmiHeader.biHeight = -bmi.bmiHeader.biHeight;
4098
4099 // Must be done only after GetDIBits() because: "The bitmap identified by the hbmp parameter
4100 // must not be selected into a device context when the application calls GetDIBits()."
4101 // (Although testing shows it works anyway, perhaps because GetDIBits() above is being
4102 // called in its informational mode only).
4103 // Note that this seems to return NULL sometimes even though everything still works.
4104 // Perhaps that is normal.
4105 tdc_orig_select = SelectObject(tdc, ahImage); // Returns NULL when we're called the second time?
4106
4107 if ( !(GetDIBits(tdc, ahImage, 0, -bmi.bmiHeader.biHeight, image_pixel, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS)) )
4108 goto end;
4109
4110 success = true; // Flag for use below.

Callers 2

PixelSearchMethod · 0.85
ImageSearchMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected