Archived

This topic is now archived and is closed to further replies.

Fix memory leak in Transparent Blit?

This topic is 5277 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

There is a major memory leak in this function and I was wondering how to fix it. Here are the 2 functions that use it:
void NEWWINDOW::TransparentBlit(HDC hdc, int destX, int destY, int destWidth, int destHeight, 
					 HDC hdc2, int srcX, int srcY, UINT tranparency)
{
	unsigned char* pImageBits = NULL;
	unsigned char* pBackBits = NULL;
	BITMAPINFO bmBitmapInfo = {0};
	HBITMAP hBitmap, hBitmap2, hOldBitmap, hOldBitmap2;
	HDC compHDC;
	HDC compHDC2;
	
	// Fill in our BitmapInfo structure (we want a 24 bit image)

	bmBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmBitmapInfo.bmiHeader.biCompression = BI_RGB;
	bmBitmapInfo.bmiHeader.biHeight = destHeight;
	bmBitmapInfo.bmiHeader.biWidth = destWidth;	
	bmBitmapInfo.bmiHeader.biBitCount = 24;
	bmBitmapInfo.bmiHeader.biClrUsed = 0;
	bmBitmapInfo.bmiHeader.biPlanes = 1;

	// Create 2 DIB Sections.  One for the Front Buffer and one for the BackBuffer

	hBitmap  = CreateDIBSection(hdc,  &bmBitmapInfo, DIB_RGB_COLORS,(void **)&pImageBits, 0,0);	
	hBitmap2  = CreateDIBSection(hdc,  &bmBitmapInfo, DIB_RGB_COLORS,(void **)&pBackBits, 0,0);

	// Create a compatible DC for the front buffer and Select our Dib Section into it

	compHDC = CreateCompatibleDC(hdc);
	hOldBitmap = (HBITMAP)SelectObject(compHDC, hBitmap);
	
	// Create a compatible DC for the back buffer and Select our Dib Section into it

	compHDC2 = CreateCompatibleDC(hdc2);
	hOldBitmap2 = (HBITMAP)SelectObject(compHDC2, hBitmap2);

	// Blit the front buffer to our compatible DC that will hold the destination bits

	BitBlt(compHDC, 0, 0, destWidth, destHeight, hdc, destX, destY, SRCCOPY);

	// Blit the back buffer to our compatible DC that will hold the source bits

	BitBlt(compHDC2, 0, 0, destWidth, destHeight, hdc2, srcX, srcY, SRCCOPY);

	// Loop through the 24 bit image (Times 3 for R G and B)

	for(int i = 0; i < destHeight * destWidth * 3; i += 3)
	{
		// Check if the current pixel being examined isn''t the transparent color

		// Remember, the image bits are stored (Blue, Green, Red), not (Red, Green, Blue)

		// We use the system macros to abstract the R G B data

		if((pBackBits[i]   != GetBValue(tranparency)) || 
		   (pBackBits[i+1] != GetGValue(tranparency)) || 
		   (pBackBits[i+2] != GetRValue(tranparency)))
		{
			// Assign the desired pixel to the foreground

			pImageBits[i]     = pBackBits[i];
			pImageBits[i + 1] = pBackBits[i + 1];
			pImageBits[i + 2] = pBackBits[i + 2];
		}
	}  

	// Blit the transparent image to the front buffer (Voila!)

	BitBlt(hdc, destX, destY, destWidth, destHeight, compHDC, 0, 0, SRCCOPY);

	// Cleanup the monochrome bitmaps

	SelectObject(compHDC, hOldBitmap);
	SelectObject(compHDC2, hOldBitmap2);	

	// Free GDI Resources

	DeleteObject(hBitmap);
	DeleteObject(hBitmap2);
	DeleteDC(compHDC);
	DeleteDC(compHDC2);
}

void NEWWINDOW::DisplayTransparentBitmap(HBITMAP hBitmap, int x, int y, RECT rPortion)
{
	// Assign the width and height to shorten variables. 

	int width = rPortion.right - rPortion.left, height = rPortion.bottom - rPortion.top;
	HDC image_dc=CreateCompatibleDC(doubleBuff.win_dc);
	// Select the bitmap handle into the extra hdc that holds the bitmap

	HBITMAP hOldBitmap = (HBITMAP) SelectObject(image_dc, hBitmap);

	// Blit the bitmap hdc into the backbuffer using the transparent color 0 (black)

	TransparentBlit(doubleBuff.back_dc, x, y, width, height, 
				    image_dc, rPortion.left, rPortion.top, RGB(255, 0, 255));

	// Select the old handle to the bitmap back where it was to clean up

	SelectObject(image_dc, hOldBitmap);
}

Share this post


Link to post
Share on other sites
Yes! After looking at every part of the code over and over for the past 2 hours, ive found the simplest thing just slid right by me.

void NEWWINDOW::DisplayTransparentBitmap(HBITMAP hBitmap, int x, int y, RECT rPortion)

I wasnt deleting the hBitmap called there.
See, the problem was in the way I called the function, it created a new bitmap every time I used it.

#define ShowTBMP(bmp, x, y, rect) DisplayTransparentBitmap((HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(bmp), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION), x, y, rect);


Thanks Super Roy and Endurion for pointing out the other delete problems.

Share this post


Link to post
Share on other sites