Archived

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

Eponick

Fix memory leak in Transparent Blit?

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