Crash allocating memory

From: Date: Mon, 25 Jul 2005 08:01:14 +0000
Subject: Crash allocating memory
Groups: php.pecl.dev 
Request: Send a blank email to pecl-dev+get-2658@lists.php.net to get a copy of this message
Hi! I'm having a problem again... a somehow weird problem, and i can't figure it out. I' have a method, which (using the windows api) alpha blends a bitmap on a device. Everything works fine, and i don't think that there are any big mistakes in there. But the method only works one or two times. After that it crashes while allocating memory (seems so). The really funny thing is, that the function works ecellent while debugging. No crash, nothing. But when running the final version from the command line, it crashes, whenever a paint event occurs (when the method is called once more). when attaching a debugger at this point, it seems that the call stack is empty and php is simply doing nothing, which seems pretty impossible to me. i can't do anything other than terminate the program. I'll post the method here, even though it's somehow a little long (sorry). Regards, Markus! P.S.: It seems like the one time it crashes at the first malloc (BITMAPINFO * bmi) and the other time it crashes at the first free occuring (regardless which variable i'm freeing, i tried this ;o)) All the macros and so on work just fine. I'm pretty sure of that ;o) i use them in about 300 other methods without problems ;o) ZEND_METHOD(xDevice, blendAlpha) { XDEVICE * pDevice; XHANDLE * pBitmap, *pParent; zval * zBitmap, *zParent = NULL; int x, y; HDC memDC; BITMAPINFO *bmi = malloc(sizeof(BITMAPINFO)); void * pvBits = NULL; BLENDFUNCTION bf; BITMAP bmp; int i, j; HBITMAP tmpbm; bool bDelete = true; bool bUseIconAplpha = true; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll|bO!", &zBitmap, &x, &y, &bUseIconAplpha, &zParent, pce_xWindow) == FAILURE) X_PARAMERROR; if(Z_TYPE_P(zBitmap) != IS_OBJECT) X_THROW("Only Objects are allowed as Parameter!"); X_GET_CONTEXT_SAVE(pDevice); if(instanceof_function(Z_OBJCE_P(zBitmap), pce_xImage TSRMLS_CC)) { zval * zType = dwl_read_prop(pce_xImage, zBitmap, "Type"); X_GET_HANDLE_SAVE_EX(pBitmap, pce_xObject, zBitmap); memDC = CreateCompatibleDC(X_DEVCONTEXT_P(pDevice)); if(Z_LVAL_P(zType) != X_IMG_BITMAP) { ICONINFO ii; GetIconInfo(X_HANDLE_P(pBitmap), &ii); tmpbm = DuplicateBitmap(ii.hbmColor); //need to preprocess all pixels here, to combine in the mask ;o) if(!bUseIconAplpha) { void * iconBits, *maskBits; int w, h; //BITMAPINFO * tmpbmi = malloc(sizeof(BITMAPINFO)); BITMAPINFO * tmpbmi = bmi; ZeroMemory(tmpbmi, sizeof(BITMAPINFO)); tmpbmi->bmiHeader.biSize = sizeof(BITMAPINFO); if(!GetDIBits(memDC, tmpbm, 0, 0, NULL, tmpbmi, DIB_RGB_COLORS)) X_THROW("Unable to load Icon Information!"); if(tmpbmi->bmiHeader.biBitCount < 32) X_THROW("Only 32 Bit Icons are allowed!"); iconBits = malloc(tmpbmi->bmiHeader.biSizeImage); maskBits = malloc(tmpbmi->bmiHeader.biSizeImage); if(!GetDIBits(memDC, tmpbm, 0, tmpbmi->bmiHeader.biHeight, iconBits, tmpbmi, DIB_RGB_COLORS)) X_THROW("Cannot get Icon Pixel data!"); if(!GetDIBits(memDC, ii.hbmMask, 0, tmpbmi->bmiHeader.biHeight, maskBits, tmpbmi, DIB_RGB_COLORS)) X_THROW("Cannot get Mask Pixel data!"); for(w = 0; w < tmpbmi->bmiHeader.biWidth; w++) { for(h = 0; h < tmpbmi->bmiHeader.biHeight; h++) { UCHAR alpha, red, green, blue; alpha = ((UINT32*)maskBits)[w+h * tmpbmi->bmiHeader.biWidth]; red = GetBValue(((UINT32*)iconBits)[w+h * tmpbmi->bmiHeader.biWidth]); green = GetGValue(((UINT32*)iconBits)[w+h * tmpbmi->bmiHeader.biWidth]); blue = GetRValue(((UINT32*)iconBits)[w+h * tmpbmi->bmiHeader.biWidth]); //Need to invert the mask Bitmap alpha values if(alpha == 0xff) { alpha = 0x00; } else { alpha = 0xff; } ((UINT32*)iconBits)[w+h * tmpbmi->bmiHeader.biWidth] = (alpha << 24) | (red << 16) | (green << 8) | (blue); } } SetDIBits(memDC, tmpbm, 0, tmpbmi->bmiHeader.biHeight, iconBits, tmpbmi, DIB_RGB_COLORS); free(iconBits); free(maskBits); } } else { tmpbm = DuplicateBitmap(X_HANDLE_P(pBitmap)); } ZeroMemory(bmi, sizeof(BITMAPINFO)); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if(!GetDIBits(memDC, tmpbm, 0, 0, NULL, bmi, DIB_RGB_COLORS)) X_THROW("Unable to retrieve Bitmap Information"); if(bmi->bmiHeader.biBitCount < 32) X_THROW("Only 32 Bit Bitmaps can be used with blendChannel!"); pvBits = malloc(bmi->bmiHeader.biSizeImage); if(!GetDIBits(memDC, tmpbm, 0, bmi->bmiHeader.biHeight, pvBits, bmi, DIB_RGB_COLORS)) X_THROW("Unable to retrieve Bitmap Bits!"); for(i = 0; i < bmi->bmiHeader.biWidth; i++) { for(j = 0; j < bmi->bmiHeader.biHeight; j++) { UCHAR uRed, uGreen, uBlue, uAlpha; float fFactor; uAlpha = ((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth] >> 24; uRed = GetBValue(((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth]); uGreen = GetGValue(((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth]); uBlue = GetRValue(((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth]); fFactor = (float)uAlpha / (float)0xff; ((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth] = (uAlpha << 24) | ((UCHAR)(uRed * fFactor) << 16) | ((UCHAR)(uGreen * fFactor) << 8) | ((UCHAR)(uBlue * fFactor)); } } SetDIBits(memDC, tmpbm, 0, bmi->bmiHeader.biHeight, pvBits, bmi, DIB_RGB_COLORS); SelectObject(memDC, tmpbm); bmp.bmWidth = bmi->bmiHeader.biWidth; bmp.bmHeight = bmi->bmiHeader.biHeight; } else if(instanceof_function(Z_OBJCE_P(zBitmap), pce_xDevice TSRMLS_CC)) { XDEVICE *pDev; X_GET_CONTEXT_SAVE_EX(pDev, pce_xDevice, zBitmap); memDC = X_DEVCONTEXT_P(pDev); bDelete = false; { HBITMAP tmp; tmp = DuplicateBitmap(SelectObject(memDC, CreateCompatibleBitmap(memDC, 0, 0))); GetObject(tmp, sizeof(BITMAP), &bmp); { ZeroMemory(bmi, sizeof(BITMAPINFO)); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if(!GetDIBits(memDC, tmp, 0, 0, NULL, bmi, DIB_RGB_COLORS)) X_THROW("Unable to retrieve Bitmap Information"); if(bmi->bmiHeader.biBitCount < 32) X_THROW("Only 32 Bit Bitmaps can be used with blendChannel!"); pvBits = malloc(bmi->bmiHeader.biSizeImage); if(!GetDIBits(memDC, tmp, 0, bmi->bmiHeader.biHeight, pvBits, bmi, DIB_RGB_COLORS)) X_THROW("Unable to retrieve Bitmap Bits!"); for(i = 0; i < bmi->bmiHeader.biWidth; i++) { for(j = 0; j < bmi->bmiHeader.biHeight; j++) { UCHAR uRed, uGreen, uBlue, uAlpha; float fFactor; uAlpha = ((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth] >> 24; uRed = GetBValue(((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth]); uGreen = GetGValue(((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth]); uBlue = GetRValue(((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth]); fFactor = (float)uAlpha / (float)0xff; ((UINT32*)pvBits)[i+j * bmi->bmiHeader.biWidth] = (uAlpha << 24) | ((UCHAR)(uRed * fFactor) << 16) | ((UCHAR)(uGreen * fFactor) << 8) | ((UCHAR)(uBlue * fFactor)); } } SetDIBits(memDC, tmp, 0, bmi->bmiHeader.biHeight, pvBits, bmi, DIB_RGB_COLORS); } DeleteObject(SelectObject(memDC, tmp)); } } else { X_THROW("Invalid Object Type passed!"); } bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.AlphaFormat = AC_SRC_ALPHA; bf.SourceConstantAlpha = 0xFF; if(zParent) { XDWORD dwExStyle; POINT pt_s; SIZE sz; X_GET_HANDLE_SAVE_EX(pParent, pce_xObject, zParent); dwExStyle = xlib_window_get_ex_style(pParent); if(!(dwExStyle & WS_EX_LAYERED)) X_THROW("Window has to be layered"); pt_s.x = 0; pt_s.y = 0; sz.cx = bmp.bmWidth; sz.cy = bmp.bmHeight; RETVAL_BOOL(UpdateLayeredWindow(X_HANDLE_P(pParent), GetDC(NULL), NULL, &sz, memDC, &pt_s, 0, &bf, ULW_ALPHA)); } else { RETVAL_BOOL(AlphaBlend( X_DEVCONTEXT_P(pDevice), x, y, bmp.bmWidth, bmp.bmHeight, memDC, 0, 0, bmp.bmWidth, bmp.bmHeight, bf)); } if(bDelete) DeleteDC(memDC); free(bmi); free(pvBits); }

« previous php.pecl.dev (#2658) next »