@@ -1097,6 +1097,51 @@ PHP_FUNCTION(imagecopyresampled)
10971097/* }}} */
10981098
10991099#ifdef PHP_WIN32
1100+ /* The bitmap must not be selected into a device context. */
1101+ static gdImagePtr php_gd_image_from_bitmap (HDC hdc , HBITMAP bitmap , int width , int height )
1102+ {
1103+ BITMAPINFO bitmap_info = {0 };
1104+ RGBQUAD * pixels ;
1105+ gdImagePtr im ;
1106+ size_t num_pixels ;
1107+ bool overflow ;
1108+ int x , y ;
1109+
1110+ bitmap_info .bmiHeader .biSize = sizeof (BITMAPINFOHEADER );
1111+ bitmap_info .bmiHeader .biWidth = width ;
1112+ /* Request a top-down DIB so its row order matches GD's. */
1113+ bitmap_info .bmiHeader .biHeight = - height ;
1114+ bitmap_info .bmiHeader .biPlanes = 1 ;
1115+ bitmap_info .bmiHeader .biBitCount = 32 ;
1116+ bitmap_info .bmiHeader .biCompression = BI_RGB ;
1117+
1118+ num_pixels = zend_safe_address ((size_t ) width , (size_t ) height , 0 , & overflow );
1119+ if (overflow ) {
1120+ return NULL ;
1121+ }
1122+
1123+ pixels = safe_emalloc (num_pixels , sizeof (* pixels ), 0 );
1124+ if (GetDIBits (hdc , bitmap , 0 , (UINT ) height , pixels , & bitmap_info , DIB_RGB_COLORS ) != height ) {
1125+ efree (pixels );
1126+ return NULL ;
1127+ }
1128+
1129+ im = gdImageCreateTrueColor (width , height );
1130+ if (im ) {
1131+ for (y = 0 ; y < height ; y ++ ) {
1132+ const RGBQUAD * src = pixels + (size_t ) y * width ;
1133+ int * dst = im -> tpixels [y ];
1134+
1135+ for (x = 0 ; x < width ; x ++ ) {
1136+ dst [x ] = gdTrueColor (src [x ].rgbRed , src [x ].rgbGreen , src [x ].rgbBlue );
1137+ }
1138+ }
1139+ }
1140+
1141+ efree (pixels );
1142+ return im ;
1143+ }
1144+
11001145/* {{{ Grab a window or its client area using a windows handle (HWND property in COM instance) */
11011146PHP_FUNCTION (imagegrabwindow )
11021147{
@@ -1144,18 +1189,8 @@ PHP_FUNCTION(imagegrabwindow)
11441189
11451190 PrintWindow (window , memDC , (UINT ) client_area );
11461191
1147- im = gdImageCreateTrueColor (Width , Height );
1148- if (im ) {
1149- int x ,y ;
1150- for (y = 0 ; y <= Height ; y ++ ) {
1151- for (x = 0 ; x <= Width ; x ++ ) {
1152- int c = GetPixel (memDC , x ,y );
1153- gdImageSetPixel (im , x , y , gdTrueColor (GetRValue (c ), GetGValue (c ), GetBValue (c )));
1154- }
1155- }
1156- }
1157-
11581192 SelectObject (memDC ,hOld );
1193+ im = php_gd_image_from_bitmap (hdc , memBM , Width , Height );
11591194 DeleteObject (memBM );
11601195 DeleteDC (memDC );
11611196 ReleaseDC ( 0 , hdc );
@@ -1198,18 +1233,8 @@ PHP_FUNCTION(imagegrabscreen)
11981233 hOld = (HBITMAP ) SelectObject (memDC , memBM );
11991234 BitBlt ( memDC , 0 , 0 , Width , Height , hdc , rc .left , rc .top , SRCCOPY );
12001235
1201- im = gdImageCreateTrueColor (Width , Height );
1202- if (im ) {
1203- int x ,y ;
1204- for (y = 0 ; y <= Height ; y ++ ) {
1205- for (x = 0 ; x <= Width ; x ++ ) {
1206- int c = GetPixel (memDC , x ,y );
1207- gdImageSetPixel (im , x , y , gdTrueColor (GetRValue (c ), GetGValue (c ), GetBValue (c )));
1208- }
1209- }
1210- }
1211-
12121236 SelectObject (memDC ,hOld );
1237+ im = php_gd_image_from_bitmap (hdc , memBM , Width , Height );
12131238 DeleteObject (memBM );
12141239 DeleteDC (memDC );
12151240 ReleaseDC ( 0 , hdc );
0 commit comments