MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / getbits

Function getbits

source/script2.cpp:3300–3410  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3298
3299
3300LPCOLORREF getbits(HBITMAP ahImage, HDC hdc, LONG &aWidth, LONG &aHeight, bool &aIs16Bit, int aMinColorDepth = 8)
3301// Helper function used by PixelSearch below.
3302// Returns an array of pixels to the caller, which it must free when done. Returns NULL on failure,
3303// in which case the contents of the output parameters is indeterminate.
3304{
3305 HDC tdc = CreateCompatibleDC(hdc);
3306 if (!tdc)
3307 return NULL;
3308
3309 // From this point on, "goto end" will assume tdc is non-NULL, but that the below
3310 // might still be NULL. Therefore, all of the following must be initialized so that the "end"
3311 // label can detect them:
3312 HGDIOBJ tdc_orig_select = NULL;
3313 LPCOLORREF image_pixel = NULL;
3314 bool success = false;
3315
3316 // Confirmed:
3317 // Needs extra memory to prevent buffer overflow due to: "A bottom-up DIB is specified by setting
3318 // the height to a positive number, while a top-down DIB is specified by setting the height to a
3319 // negative number. THE BITMAP COLOR TABLE WILL BE APPENDED to the BITMAPINFO structure."
3320 // Maybe this applies only to negative height, in which case the second call to GetDIBits()
3321 // below uses one.
3322 struct BITMAPINFO3
3323 {
3324 BITMAPINFOHEADER bmiHeader;
3325 RGBQUAD bmiColors[260]; // v1.0.40.10: 260 vs. 3 to allow room for color table when color depth is 8-bit or less.
3326 } bmi;
3327
3328 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3329 bmi.bmiHeader.biBitCount = 0; // i.e. "query bitmap attributes" only.
3330 if (!GetDIBits(tdc, ahImage, 0, 0, NULL, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS)
3331 || bmi.bmiHeader.biBitCount < aMinColorDepth) // Relies on short-circuit boolean order.
3332 goto end;
3333
3334 // Set output parameters for caller:
3335 aIs16Bit = (bmi.bmiHeader.biBitCount == 16);
3336 aWidth = bmi.bmiHeader.biWidth;
3337 aHeight = bmi.bmiHeader.biHeight;
3338
3339 int image_pixel_count = aWidth * aHeight;
3340 if ( !(image_pixel = (LPCOLORREF)malloc(image_pixel_count * sizeof(COLORREF))) )
3341 goto end;
3342
3343 // v1.0.40.10: To preserve compatibility with callers who check for transparency in icons, don't do any
3344 // of the extra color table handling for 1-bpp images. Update: For code simplification, support only
3345 // 8-bpp images. If ever support lower color depths, use something like "bmi.bmiHeader.biBitCount > 1
3346 // && bmi.bmiHeader.biBitCount < 9";
3347 bool is_8bit = (bmi.bmiHeader.biBitCount == 8);
3348 if (!is_8bit)
3349 bmi.bmiHeader.biBitCount = 32;
3350 bmi.bmiHeader.biHeight = -bmi.bmiHeader.biHeight; // Storing a negative inside the bmiHeader struct is a signal for GetDIBits().
3351
3352 // Must be done only after GetDIBits() because: "The bitmap identified by the hbmp parameter
3353 // must not be selected into a device context when the application calls GetDIBits()."
3354 // (Although testing shows it works anyway, perhaps because GetDIBits() above is being
3355 // called in its informational mode only).
3356 // Note that this seems to return NULL sometimes even though everything still works.
3357 // Perhaps that is normal.

Callers 2

PixelSearchFunction · 0.85
BIF_DECLFunction · 0.85

Calls 1

rgb_to_bgrFunction · 0.85

Tested by

no test coverage detected