예제 #1
0
static BOOLEAN WriteMemory(HBITMAP hManager, HBITMAP hWorker, PVOID dest, PVOID src, DWORD len) {
		
	if (SetBitmapBits(hManager, sizeof(PVOID), &dest) == 0) {
		LOG("[-] Unable To Set Destination Address: 0x%p\n", dest);
		return FALSE;
	}

	return SetBitmapBits(hWorker, len, src) ? TRUE : FALSE;
}
예제 #2
0
파일: trace.c 프로젝트: mingpen/OpenNT
long far pascal zSetBitmapBits( HBITMAP pp1, DWORD pp2, LPSTR pp3 )
{
    long r;

    SaveRegs();
    /*
    ** Log IN Parameters (No Create/Destroy Checking Yet!)
    */
    LogIn( (LPSTR)"APICALL:SetBitmapBits HBITMAP+DWORD+FixedString+",
        pp1, pp2, pp3, pp2 );

    /*
    ** Call the API!
    */
    RestoreRegs();
    GrovelDS();
    r = SetBitmapBits(pp1,pp2,pp3);
    UnGrovelDS();
    SaveRegs();
    /*
    ** Log Return Code & OUT Parameters (No Create/Destroy Checking Yet!)
    */
    LogOut( (LPSTR)"APIRET:SetBitmapBits long++++",
        r, (short)0, (short)0, (short)0 );

    RestoreRegs();
    return( r );
}
예제 #3
0
void CovertToGrayBitmap(HBITMAP hSourceBmp, HDC sourceDc)
{
	HBITMAP retBmp = hSourceBmp;
	BITMAPINFO bmpInfo;
	ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
	bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	GetDIBits(sourceDc, retBmp, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS);

	BYTE* bits = new BYTE[bmpInfo.bmiHeader.biSizeImage];
	GetBitmapBits(retBmp, bmpInfo.bmiHeader.biSizeImage, bits);

	int bytePerPixel = 4;//默认32位
	if (bmpInfo.bmiHeader.biBitCount == 24)
	{
		bytePerPixel = 3;
	}
	for (DWORD i = 0; i < bmpInfo.bmiHeader.biSizeImage; i += bytePerPixel)
	{
		BYTE r = *(bits + i);
		BYTE g = *(bits + i + 1);
		BYTE b = *(bits + i + 2);
		*(bits + i) = *(bits + i + 1) = *(bits + i + 2) = (r + b + g) / 3;
	}
	SetBitmapBits(hSourceBmp, bmpInfo.bmiHeader.biSizeImage, bits);
	delete[] bits;
}
예제 #4
0
//************************************
// Method:    RayTracer
// FullName:  Трассировка лучей
// Access:    public 
// Returns:   void
// Qualifier:
// Parameter: HBITMAP bitmap - идентификатор bitmap на который отрендерится картинка
// Parameter: CSphere S[] - массив из сфер, пока что так
// Parameter: CRVector3D lightsArray[] - массив из точечных источников света
//************************************
void RayTracer(HBITMAP bitmap,CSphere S[], CVector3D lightsArray[], CBox sceneBox)
{
	CVector2D tt;
	int i,j;
	float a,b,c,D,t,coefLight;
	CVector3D rayVector,snormal,lightdir,light;
	//Выбрасываем каждый луч
	for(i=-YRES/2;i<YRES/2;i++)
	{
		for(j=-XRES/2;j<XRES/2;j++)
		{
			//Изначально задаем цвет фона
			buffer[i+YRES/2][j+XRES/2]=BACKGROUND_COLOR;
			//Вычиляем вектор для луча
			rayVector.x=(j)*2.0f/XRES;		
			rayVector.y=(i)*2.0f/YRES;		
			rayVector.z=DIST;	
			//Нормализуем вектор
			rayVector.NormalizeVector();
			CVector3D hit;
			CVector3D eye(0,0,0);
			CRay ray(eye,rayVector);
			RGBQUAD currentColor=TraceOneRay(ray,S,lightsArray,1,sceneBox);
			buffer[i+YRES/2][j+XRES/2]= RGB(currentColor.rgbRed,currentColor.rgbGreen,currentColor.rgbBlue);
			
		}
	}
	SetBitmapBits(bitmap,XRES*YRES*sizeof(buffer[0][0]),buffer);
	memset(buffer,25,XRES*YRES*sizeof(buffer[0][0]));
}
예제 #5
0
void HalfBitmap32Alpha(HBITMAP hBitmap)
{
	BITMAP bmp;
	DWORD dwLen;
	BYTE *p;
	int x, y;

	GetObject(hBitmap, sizeof(bmp), &bmp);

	if (bmp.bmBitsPixel != 32)
		return;

	dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8);
	p = (BYTE *)malloc(dwLen);
	if (p == NULL)
		return;
	memset(p, 0, dwLen);

	GetBitmapBits(hBitmap, dwLen, p);

	for (y = 0; y < bmp.bmHeight; ++y) {
        BYTE *px = p + bmp.bmWidth * 4 * y;

        for (x = 0; x < bmp.bmWidth; ++x) 
		{
			px[3]>>=1;
			px += 4;
		}
	}

	SetBitmapBits(hBitmap, dwLen, p);

	free(p);
}
예제 #6
0
파일: gfx.cpp 프로젝트: Seldom/miranda-ng
void Gfx::preMultiply(HBITMAP hBitmap, int mode)
{
	DWORD dwLen;
    int width, height, x, y;
    BITMAP bmp;
    BYTE alpha;

	GetObject(hBitmap, sizeof(bmp), &bmp);
    width = bmp.bmWidth;
	height = bmp.bmHeight;
	dwLen = width * height * 4;
	if (dwLen > m_sAllocated) {
		m_p = (BYTE *)realloc(m_p, dwLen);
		m_sAllocated = dwLen;
	}
    if(m_p) {
        GetBitmapBits(hBitmap, dwLen, m_p);
        for (y = 0; y < height; ++y) {
            BYTE *px = m_p + width * 4 * y;

            for (x = 0; x < width; ++x) {
                if(mode) {
                    alpha = px[3];
                    px[0] = px[0] * alpha/255;
                    px[1] = px[1] * alpha/255;
                    px[2] = px[2] * alpha/255;
                }
                else
                    px[3] = 255;
                px += 4;
            }
        }
        dwLen = SetBitmapBits(hBitmap, dwLen, m_p);
    }
}
예제 #7
0
Emoticon::Emoticon(const tstring& _emoticonText, const string& _imagePath) : 
	emoticonText(_emoticonText), imagePath(_imagePath)
{
	emoticonBitmap = (HBITMAP) ::LoadImage(0, Text::toT(imagePath).c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
	if(!emoticonBitmap)
		return;
	
	BITMAP bm = { 0 };
	GetObject(emoticonBitmap, sizeof(bm), &bm);
	
	if(bm.bmBitsPixel == 32) {
		BYTE *pBits = new BYTE[bm.bmWidth * bm.bmHeight * 4];
		GetBitmapBits(emoticonBitmap, bm.bmWidth * bm.bmHeight * 4, pBits);
		
		// fix alpha channel	
		for (int y = 0; y < bm.bmHeight; y++) {
			BYTE * pPixel = (BYTE *) pBits + bm.bmWidth * 4 * y;

			for (int x = 0; x < bm.bmWidth; x++) {
				pPixel[0] = pPixel[0] * pPixel[3] / 255; 
				pPixel[1] = pPixel[1] * pPixel[3] / 255; 
				pPixel[2] = pPixel[2] * pPixel[3] / 255; 

				pPixel += 4;
			}
		}
		SetBitmapBits(emoticonBitmap, bm.bmWidth * bm.bmHeight * 4, pBits);
	    
		delete[] pBits;
	}
}
예제 #8
0
파일: gfx.cpp 프로젝트: Seldom/miranda-ng
void Gfx::setBitmapAlpha(HBITMAP hBitmap, BYTE bAlpha)
{
	BITMAP bmp;
	DWORD dwLen;
	int x, y;

	GetObject(hBitmap, sizeof(bmp), &bmp);

	if (bmp.bmBitsPixel != 32)
		return;

	dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8);
	if (dwLen > m_sAllocated) {
		m_p = (BYTE *)realloc(m_p, dwLen);
		m_sAllocated = dwLen;
	}
	memset(m_p, 0, dwLen);

	GetBitmapBits(hBitmap, dwLen, m_p);

	for (y = 0; y < bmp.bmHeight; ++y) {
		BYTE *px = m_p + bmp.bmWidth * 4 * y;

		for (x = 0; x < bmp.bmWidth; ++x) {
			px[3] = bAlpha;
			px += 4;
		}
	}
	SetBitmapBits(hBitmap, bmp.bmWidth * bmp.bmHeight * 4, m_p);
}
예제 #9
0
static LONG ReadMemory(HBITMAP hManager, HBITMAP hWorker, PVOID src, PVOID dest, DWORD len) {
	
	if (SetBitmapBits(hManager, sizeof(PVOID), &src) == 0) {
		LOG("[-] Unable To Set Source Address: 0x%p\n", src);
		return FALSE;
	}
	
	return GetBitmapBits(hWorker, len, dest) ? TRUE : FALSE;
}
예제 #10
0
파일: win32.c 프로젝트: yydaor/LCUI
LCUI_API void
LCUIScreen_SyncFrameBuffer( void )
{
	SetBitmapBits( client_bitmap, LCUI_Sys.screen.smem_len, LCUI_Sys.screen.fb_mem );
	/* 将帧缓冲内的位图数据更新至客户区内指定区域(area) */
	BitBlt( hdc_client, 0, 0, LCUI_Sys.screen.size.w, LCUI_Sys.screen.size.h, 
		hdc_framebuffer, 0, 0, SRCCOPY );
	ValidateRect( current_hwnd, NULL );
}
예제 #11
0
/*
 * __SetBitmapBits - make sure to get alias right for bits
 */
LONG FAR PASCAL __SetBitmapBits( HBITMAP bm, DWORD dw, LPSTR bits )
{
    DWORD       alias;
    LONG        rc;

    DPMIGetHugeAlias( (DWORD) bits, &alias, dw );
    rc = SetBitmapBits( bm, dw, (LPSTR) alias );
    DPMIFreeHugeAlias( alias, dw );
    return( rc );

} /* __SetBitmapBits */
예제 #12
0
static
BOOL xxPoint(LONG id, DWORD Value)
{
    LONG iLeng = 0x00;
    pBmpHunted[id] = Value;
    iLeng = SetBitmapBits(hBmpHunted, 0xD00, pBmpHunted);
    if (iLeng < 0xD00)
    {
        return FALSE;
    }
    return TRUE;
}
예제 #13
0
파일: gfx.cpp 프로젝트: Seldom/miranda-ng
void Gfx::deSaturate(HBITMAP hBitmap, bool fReduceContrast)
{
	BITMAP 	bmp;
	DWORD 	dwLen;
	BYTE	bMin = 255, bMax = 0, bRamp = 0, bMaxAdjust, bMinAdjust;

	int 	x, y;

	GetObject(hBitmap, sizeof(bmp), &bmp);

	if (bmp.bmBitsPixel != 32)
		return;

	dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8);
	if (dwLen > m_sAllocated) {
		m_p = (BYTE *)realloc(m_p, dwLen);
		m_sAllocated = dwLen;
	}
	memset(m_p, 0, dwLen);

	GetBitmapBits(hBitmap, dwLen, m_p);

	if(fReduceContrast) {
		for (y = 0; y < bmp.bmHeight; ++y) {
			BYTE *px = m_p + bmp.bmWidth * 4 * y;

			for (x = 0; x < bmp.bmWidth; ++x) {
				BYTE avg = (px[0] + px[1] + px[2]) / 3;
				bMin = min(avg, bMin);
				bMax = max(avg, bMax);
				px += 4;
			}
		}
		bRamp = (bMax + bMin) / 2;
		bMaxAdjust = (bMax - bRamp) / 2;
		bMinAdjust = (bRamp - bMin) / 2;
	}
	for (y = 0; y < bmp.bmHeight; ++y) {
		BYTE *px = m_p + bmp.bmWidth * 4 * y;

		for (x = 0; x < bmp.bmWidth; ++x) {
			BYTE avg = (px[0] + px[1] + px[2]) / 3;
			//if(fReduceContrast)
			//	avg = (avg < bRamp ? avg + bMinAdjust : avg - bMaxAdjust);
			px[0] = px[1] = px[2] = avg;
			px += 4;
		}
	}
	SetBitmapBits(hBitmap, bmp.bmWidth * bmp.bmHeight * 4, m_p);
}
예제 #14
0
HBITMAP CopyBitmapTo32(HBITMAP hBitmap)
{
	BITMAP bmp;
	GetObject(hBitmap, sizeof(bmp), &bmp);

	DWORD dwLen = bmp.bmWidth * bmp.bmHeight * 4;
	BYTE *p = (BYTE *)malloc(dwLen);
	if (p == nullptr)
		return nullptr;

	// Create bitmap
	BITMAPINFO RGB32BitsBITMAPINFO;
	memset(&RGB32BitsBITMAPINFO, 0, sizeof(BITMAPINFO));
	RGB32BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	RGB32BitsBITMAPINFO.bmiHeader.biWidth = bmp.bmWidth;
	RGB32BitsBITMAPINFO.bmiHeader.biHeight = bmp.bmHeight;
	RGB32BitsBITMAPINFO.bmiHeader.biPlanes = 1;
	RGB32BitsBITMAPINFO.bmiHeader.biBitCount = 32;

	BYTE *ptPixels;
	HBITMAP hDirectBitmap = CreateDIBSection(nullptr, (BITMAPINFO *)&RGB32BitsBITMAPINFO, DIB_RGB_COLORS, (void **)&ptPixels, nullptr, 0);

	// Copy data
	if (bmp.bmBitsPixel != 32) {
		HDC hdcOrig = CreateCompatibleDC(nullptr);
		HBITMAP oldOrig = (HBITMAP)SelectObject(hdcOrig, hBitmap);

		HDC hdcDest = CreateCompatibleDC(nullptr);
		HBITMAP oldDest = (HBITMAP)SelectObject(hdcDest, hDirectBitmap);

		BitBlt(hdcDest, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOrig, 0, 0, SRCCOPY);

		SelectObject(hdcDest, oldDest);
		DeleteObject(hdcDest);
		SelectObject(hdcOrig, oldOrig);
		DeleteObject(hdcOrig);

		// Set alpha
		FreeImage_CorrectBitmap32Alpha(hDirectBitmap, FALSE);
	}
	else {
		GetBitmapBits(hBitmap, dwLen, p);
		SetBitmapBits(hDirectBitmap, dwLen, p);
	}

	free(p);

	return hDirectBitmap;
}
예제 #15
0
// Correct alpha from bitmaps loaded without it (it cames with 0 and should be 255)
void CorrectBitmap32Alpha(HBITMAP hBitmap, BOOL force)
{
	BITMAP bmp;
	DWORD dwLen;
	BYTE *p;
	int x, y;
	BOOL fixIt;

	GetObject(hBitmap, sizeof(bmp), &bmp);

	if (bmp.bmBitsPixel != 32)
		return;

	dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8);
	p = (BYTE *)malloc(dwLen);
	if (p == NULL)
		return;
	memset(p, 0, dwLen);

	GetBitmapBits(hBitmap, dwLen, p);

	fixIt = TRUE;
	for (y = 0; fixIt && y < bmp.bmHeight; ++y) {
        BYTE *px = p + bmp.bmWidth * 4 * y;

        for (x = 0; fixIt && x < bmp.bmWidth; ++x) 
		{
			if (px[3] != 0 && !force) 
			{
				fixIt = FALSE;
			}
			else
			{
				if (px[0] != 0 || px[1] != 0 || px[2] != 0)
					px[3] = 255;
			}

			px += 4;
		}
	}

	if (fixIt)
		SetBitmapBits(hBitmap, dwLen, p);

	free(p);
}
예제 #16
0
/**********************************************************************
 *		BITMAP_CopyBitmap
 *
 */
HBITMAP BITMAP_CopyBitmap(HBITMAP hbitmap)
{
    HBITMAP res = 0;
    BITMAP bm;

    if (!GetObjectW( hbitmap, sizeof(bm), &bm )) return 0;
    res = CreateBitmapIndirect(&bm);

    if(res) {
        char *buf = HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes *
			       bm.bmHeight );
        GetBitmapBits (hbitmap, bm.bmWidthBytes * bm.bmHeight, buf);
	SetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
	HeapFree( GetProcessHeap(), 0, buf );
    }
    return res;
}
예제 #17
0
// Make a bitmap all transparent, but only if it is a 32bpp
void MakeBmpTransparent(HBITMAP hBitmap)
{
	BITMAP bmp;
	GetObject(hBitmap, sizeof(bmp), &bmp);
	if (bmp.bmBitsPixel != 32)
		return;

	DWORD dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8);
	BYTE *p = (BYTE *)malloc(dwLen);
	if (p == nullptr)
		return;

	memset(p, 0, dwLen);
	SetBitmapBits(hBitmap, dwLen, p);

	free(p);
}
예제 #18
0
BOOL MakeGrayscale(HBITMAP *hBitmap)
{
	BYTE *p = NULL;
	BYTE *p1;
	DWORD dwLen;
    int width, height, x, y;
    BITMAP bmp;

	GetObject(*hBitmap, sizeof(bmp), &bmp);
    width = bmp.bmWidth;
	height = bmp.bmHeight;

	dwLen = width * height * 4;
	p = (BYTE *)malloc(dwLen);
    if (p == NULL) 
	{
		return FALSE;
	}

	if (bmp.bmBitsPixel != 32)
	{
		// Convert to 32 bpp
		HBITMAP hBmpTmp = CopyBitmapTo32(*hBitmap);
		DeleteObject(*hBitmap);
		*hBitmap = hBmpTmp;
	} 
	GetBitmapBits(*hBitmap, dwLen, p);

	// Make grayscale
	for (y = 0 ; y < height ; y++)
	{
		for (x = 0 ; x < width ; x++)
		{
			p1 = GET_PIXEL(p, x, y);
			p1[0] = p1[1] = p1[2] = ( p1[0] + p1[1] + p1[2] ) / 3;
		}
	}

    dwLen = SetBitmapBits(*hBitmap, dwLen, p);
    free(p);

	return TRUE;
}
예제 #19
0
파일: bitmap.c 프로젝트: mikekap/wine
/**********************************************************************
 *		BITMAP_CopyBitmap
 *
 */
HBITMAP BITMAP_CopyBitmap(HBITMAP hbitmap)
{
    HBITMAP res;
    DIBSECTION dib;
    DWORD size;

    if (!(size = GetObjectW( hbitmap, sizeof(dib), &dib ))) return 0;

    if (size == sizeof(DIBSECTION))
    {
        void *bits;
        BITMAPINFO *bi;
        HDC dc = CreateCompatibleDC( NULL );

        if (!dc) return 0;
        if (!(bi = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ))))
        {
            DeleteDC( dc );
            return 0;
        }
        bi->bmiHeader = dib.dsBmih;

        /* Get the color table or the color masks */
        GetDIBits( dc, hbitmap, 0, 0, NULL, bi, DIB_RGB_COLORS );

        res = CreateDIBSection( dc, bi, DIB_RGB_COLORS, &bits, NULL, 0 );
        if (res) SetDIBits( dc, res, 0, dib.dsBm.bmHeight, dib.dsBm.bmBits, bi, DIB_RGB_COLORS );
        HeapFree( GetProcessHeap(), 0, bi );
        DeleteDC( dc );
        return res;
    }

    res = CreateBitmapIndirect( &dib.dsBm );
    if(res) {
        char *buf = HeapAlloc( GetProcessHeap(), 0, dib.dsBm.bmWidthBytes * dib.dsBm.bmHeight );
        GetBitmapBits (hbitmap, dib.dsBm.bmWidthBytes * dib.dsBm.bmHeight, buf);
        SetBitmapBits (res, dib.dsBm.bmWidthBytes * dib.dsBm.bmHeight, buf);
	HeapFree( GetProcessHeap(), 0, buf );
    }
    return res;
}
예제 #20
0
static
BOOL xxPointToGet(LONG addr, PVOID pvBits, DWORD cb)
{
    BOOL iLeng = 0;
    pBmpHunted[iExtPalColor] = addr;
    iLeng = SetBitmapBits(hBmpHunted, 0xD00, pBmpHunted);
    if (iLeng < 0xD00)
    {
        return FALSE;
    }
    PVOID pvTable = NULL;
    UINT cbSize = (cb + 3) & ~3; // sizeof(PALETTEENTRY) => 4
    pvTable = malloc(cbSize);
    iLeng = GetPaletteEntries(hPalExtend, 0, cbSize / 4, (PPALETTEENTRY)pvTable);
    memcpy(pvBits, pvTable, cb);
    free(pvTable);
    if (iLeng < cbSize / 4)
    {
        return FALSE;
    }
    return TRUE;
}
예제 #21
0
파일: main.cpp 프로젝트: Seldom/miranda-ng
/*
* needed for per pixel transparent images. Such images should then be rendered by
* using AlphaBlend() with AC_SRC_ALPHA
* dwFlags will be set to AVS_PREMULTIPLIED
* return TRUE if the image has at least one pixel with transparency
*/
static BOOL FreeImage_PreMultiply(HBITMAP hBitmap)
{
	BOOL transp = FALSE;

	BITMAP bmp;
	GetObject(hBitmap, sizeof(bmp), &bmp);
	if (bmp.bmBitsPixel == 32) {
		int width = bmp.bmWidth;
		int height = bmp.bmHeight;
		int dwLen = width * height * 4;
		BYTE *p = (BYTE *)malloc(dwLen);
		if (p != NULL) {
			GetBitmapBits(hBitmap, dwLen, p);

			for (int y = 0; y < height; ++y) {
				BYTE *px = p + width * 4 * y;
				for (int x = 0; x < width; ++x) {
					BYTE alpha = px[3];
					if (alpha < 255) {
						transp = TRUE;

						px[0] = px[0] * alpha/255;
						px[1] = px[1] * alpha/255;
						px[2] = px[2] * alpha/255;
					}

					px += 4;
				}
			}

			if (transp)
				dwLen = SetBitmapBits(hBitmap, dwLen, p);
			free(p);
		}
	}

	return transp;
}
예제 #22
0
// Set the color of points that are transparent
void SetTranspBkgColor(HBITMAP hBitmap, COLORREF color)
{
	BITMAP bmp;
	GetObject(hBitmap, sizeof(bmp), &bmp);

	if (bmp.bmBitsPixel != 32)
		return;

	DWORD dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8);
	BYTE *p = (BYTE *)malloc(dwLen);
	if (p == nullptr)
		return;
	memset(p, 0, dwLen);

	GetBitmapBits(hBitmap, dwLen, p);

	bool changed = false;
	for (int y = 0; y < bmp.bmHeight; ++y) {
		BYTE *px = p + bmp.bmWidth * 4 * y;

		for (int x = 0; x < bmp.bmWidth; ++x) {
			if (px[3] == 0) {
				px[0] = GetBValue(color);
				px[1] = GetGValue(color);
				px[2] = GetRValue(color);
				changed = true;
			}
			px += 4;
		}
	}

	if (changed)
		SetBitmapBits(hBitmap, dwLen, p);

	free(p);
}
예제 #23
0
LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
        
{
	static int startx = START_X, starty = START_Y;
	static HBITMAP hBitmap;
	static int                    cxClient, cyClient, cxSource, cySource ;
	HDC                           hdc, hdcMem ;
	int                           x, y ;
	PAINTSTRUCT                  ps ;

 	int i;

	switch (message)
	{
		case   WM_CREATE:
			test_init();
			return 0 ;
			
		case   WM_SIZE:
			return 0 ;
		case   WM_TIMER:
			OutputDebugString("TIMER");
			//Invalidate();
			g_frame_id+=1;
			if(g_frame_id >= g_frame_num)
				g_frame_id=0;
			//SendMessage(hwnd, WM_PAINT, 0, 0);
			InvalidateRect(hwnd, NULL, FALSE);
			return 1;
			
		case   WM_PAINT:
			cxSource      = WIDTH;
			cySource      = HEIGHT;
			cxClient = WIDTH;
			cyClient = HEIGHT;
			OutputDebugString("Paint\n");
			
			hdc = GetDC (hwnd);
			hdcMem = CreateCompatibleDC (hdc);
			hBitmap = CreateCompatibleBitmap (hdc, WIDTH, HEIGHT);

			fill_datas();
			
			SetBitmapBits(hBitmap, sizeof datas, datas);
			GetBitmapBits(hBitmap, sizeof datas, datas);				

			ReleaseDC (hwnd, hdc) ;
			SelectObject (hdcMem, hBitmap) ;
			
			hdc = BeginPaint(hwnd, &ps);
			for (y = starty ; y < starty + cyClient ; y += cySource)
			{
				for (x = startx ; x < startx + cxClient ; x += cxSource)
				{
					BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ;
					//StretchBlt (hdc, x, y, cxClient, cyClient,hdcMem, 0, 0, cxSource, cySource, MERGECOPY) ;
				}
			}
			EndPaint (hwnd, &ps) ;
			DeleteDC (hdcMem) ;
			DeleteObject (hBitmap) ;
			return 0 ;
			
		case   WM_DESTROY:
			PostQuitMessage (0) ;
			test_end();
			return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
예제 #24
0
파일: bitmap.c 프로젝트: MortenRoenne/wine
/******************************************************************************
 * CreateBitmapIndirect [GDI32.@]
 *
 * Creates a bitmap with the specified info.
 *
 * PARAMS
 *  bmp [I] Pointer to the bitmap info describing the bitmap
 *
 * RETURNS
 *    Success: Handle to bitmap
 *    Failure: NULL. Use GetLastError() to determine the cause.
 *
 * NOTES
 *  If a width or height of 0 are given, a 1x1 monochrome bitmap is returned.
 */
HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
{
    BITMAP bm;
    BITMAPOBJ *bmpobj;
    HBITMAP hbitmap;

    if (!bmp || bmp->bmType)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return NULL;
    }

    if (bmp->bmWidth > 0x7ffffff || bmp->bmHeight > 0x7ffffff)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return 0;
    }

    bm = *bmp;

    if (!bm.bmWidth || !bm.bmHeight)
    {
        return GetStockObject( DEFAULT_BITMAP );
    }
    else
    {
        if (bm.bmHeight < 0)
            bm.bmHeight = -bm.bmHeight;
        if (bm.bmWidth < 0)
            bm.bmWidth = -bm.bmWidth;
    }

    if (bm.bmPlanes != 1)
    {
        FIXME("planes = %d\n", bm.bmPlanes);
        SetLastError( ERROR_INVALID_PARAMETER );
        return NULL;
    }

    /* Windows only uses 1, 4, 8, 16, 24 and 32 bpp */
    if(bm.bmBitsPixel == 1)         bm.bmBitsPixel = 1;
    else if(bm.bmBitsPixel <= 4)    bm.bmBitsPixel = 4;
    else if(bm.bmBitsPixel <= 8)    bm.bmBitsPixel = 8;
    else if(bm.bmBitsPixel <= 16)   bm.bmBitsPixel = 16;
    else if(bm.bmBitsPixel <= 24)   bm.bmBitsPixel = 24;
    else if(bm.bmBitsPixel <= 32)   bm.bmBitsPixel = 32;
    else {
        WARN("Invalid bmBitsPixel %d, returning ERROR_INVALID_PARAMETER\n", bm.bmBitsPixel);
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    /* Windows ignores the provided bm.bmWidthBytes */
    bm.bmWidthBytes = get_bitmap_stride( bm.bmWidth, bm.bmBitsPixel );
    /* XP doesn't allow to create bitmaps larger than 128 Mb */
    if (bm.bmHeight > 128 * 1024 * 1024 / bm.bmWidthBytes)
    {
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
        return 0;
    }

    /* Create the BITMAPOBJ */
    if (!(bmpobj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*bmpobj) )))
    {
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
        return 0;
    }

    bmpobj->dib.dsBm = bm;
    bmpobj->dib.dsBm.bmBits = NULL;

    if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs )))
    {
        HeapFree( GetProcessHeap(), 0, bmpobj );
        return 0;
    }

    if (bm.bmBits)
        SetBitmapBits( hbitmap, bm.bmHeight * bm.bmWidthBytes, bm.bmBits );

    TRACE("%dx%d, bpp %d planes %d: returning %p\n", bm.bmWidth, bm.bmHeight,
          bm.bmBitsPixel, bm.bmPlanes, hbitmap);

    return hbitmap;
}
예제 #25
0
DWORD CALLBACK HelDdSurfUnlock(LPDDHAL_UNLOCKDATA lpUnLockData)
{
    HDC hDC;
    HBITMAP hImage = NULL;

    HDC hMemDC = NULL;
    HBITMAP hDCBmp = NULL;
    BITMAP bm = {0};

    DX_WINDBG_trace();

    /* Get our hdc for the active window */
    hDC = GetDC((HWND)lpUnLockData->lpDDSurface->lpSurfMore->lpDD_lcl->hFocusWnd);

    if (hDC != NULL)
    {
        /* Create a memory bitmap to store a copy of current hdc surface */

        /* fixme the rcarea are not store in the struct yet so the data will look corupted */
        hImage = CreateCompatibleBitmap (hDC, lpUnLockData->lpDDSurface->lpGbl->wWidth, lpUnLockData->lpDDSurface->lpGbl->wHeight);

        /* Create a memory hdc so we can draw on our current memory bitmap */
        hMemDC = CreateCompatibleDC(hDC);

        if (hMemDC != NULL)
        {
            /* Select our memory bitmap to our memory hdc */
            hDCBmp = (HBITMAP) SelectObject (hMemDC, hImage);

            /* Get our memory bitmap information */
            GetObject(hImage, sizeof(BITMAP), &bm);

            SetBitmapBits(hImage,bm.bmWidthBytes * bm.bmHeight, lpUnLockData->lpDDSurface->lpSurfMore->lpDDRAWReserved2);

            BitBlt (hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);

            SelectObject (hMemDC, hDCBmp);

            /* Setup return value */
             lpUnLockData->ddRVal = DD_OK;
        }
    }

    /* Cleanup after us */
    if (hImage != NULL)
    {
        DeleteObject (hImage);
    }

    if (hMemDC != NULL)
    {
        DeleteDC (hMemDC);
    }

    if (lpUnLockData->lpDDSurface->lpSurfMore->lpDDRAWReserved2 != NULL)
    {
        HeapFree(GetProcessHeap(), 0, lpUnLockData->lpDDSurface->lpSurfMore->lpDDRAWReserved2 );
    }

    return DDHAL_DRIVER_HANDLED;
}
예제 #26
0
파일: caret.c 프로젝트: bilboed/wine
/*****************************************************************
 *		CreateCaret (USER32.@)
 */
BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap, INT width, INT height )
{
    BOOL ret;
    RECT r;
    int old_state = 0;
    int hidden = 0;
    HBITMAP hBmp = 0;
    HWND prev = 0;

    TRACE("hwnd=%p\n", hwnd);

    if (!hwnd) return FALSE;

    if (bitmap && (bitmap != (HBITMAP)1))
    {
        BITMAP bmp;
        if (!GetObjectA( bitmap, sizeof(bmp), &bmp )) return FALSE;
        width = bmp.bmWidth;
        height = bmp.bmHeight;
	bmp.bmBits = NULL;
	hBmp = CreateBitmapIndirect(&bmp);
	if (hBmp)
	{
	    /* copy the bitmap */
	    LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, bmp.bmWidthBytes * bmp.bmHeight);
	    GetBitmapBits(bitmap, bmp.bmWidthBytes * bmp.bmHeight, buf);
	    SetBitmapBits(hBmp, bmp.bmWidthBytes * bmp.bmHeight, buf);
	    HeapFree(GetProcessHeap(), 0, buf);
	}
    }
    else
    {
	HDC hdc;

        if (!width) width = GetSystemMetrics(SM_CXBORDER);
        if (!height) height = GetSystemMetrics(SM_CYBORDER);

	/* create the uniform bitmap on the fly */
	hdc = GetDC(hwnd);
	if (hdc)
	{
	    HDC hMemDC = CreateCompatibleDC(hdc);
	    if (hMemDC)
	    {
		if ((hBmp = CreateCompatibleBitmap(hMemDC, width, height )))
		{
		    HBITMAP hPrevBmp = SelectObject(hMemDC, hBmp);
                    SetRect( &r, 0, 0, width, height );
		    FillRect(hMemDC, &r, ULongToHandle((bitmap ? COLOR_GRAYTEXT : COLOR_WINDOW) + 1));
		    SelectObject(hMemDC, hPrevBmp);
		}
		DeleteDC(hMemDC);
	    }
	    ReleaseDC(hwnd, hdc);
	}
    }
    if (!hBmp) return FALSE;

    SERVER_START_REQ( set_caret_window )
    {
        req->handle = wine_server_user_handle( hwnd );
        req->width  = width;
        req->height = height;
        if ((ret = !wine_server_call_err( req )))
        {
            prev      = wine_server_ptr_handle( reply->previous );
            r.left    = reply->old_rect.left;
            r.top     = reply->old_rect.top;
            r.right   = reply->old_rect.right;
            r.bottom  = reply->old_rect.bottom;
            old_state = reply->old_state;
            hidden    = reply->old_hide;
        }
    }
    SERVER_END_REQ;
    if (!ret) return FALSE;

    if (prev && !hidden)  /* hide the previous one */
    {
        /* FIXME: won't work if prev belongs to a different process */
        KillSystemTimer( prev, TIMERID );
        if (old_state) CARET_DisplayCaret( prev, &r );
    }

    if (Caret.hBmp) DeleteObject( Caret.hBmp );
    Caret.hBmp = hBmp;
    Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 );
    return TRUE;
}
예제 #27
0
void plD_DrawImage_win3(PLStream *pls)
{
  WinDev *dev = (WinDev *) pls->dev;
  HDC hdcMemory;

  HBITMAP bitmap, bitmapOld;
  BYTE    *byteArray;
	
  int     byteArrayXsize, byteArrayYsize;
  int     imageX0, imageY0, imageWX, imageWY;
  int     image_kx_start, image_ky_start, image_kx_end, image_ky_end, image_wkx, image_wky;
  int     imageXmin, imageXmax, imageYmin, imageYmax;

  int i, npts, nx, ny, ix, iy, corners[5], Ppts_x[5], Ppts_y[5];
  int clpxmi, clpxma, clpymi, clpyma, icol1;

  int level;
  float wcxmi, wcxma, wcymi, wcyma;
  long ptr1, ptr2;

  clpxmi = plsc->imclxmin;
  clpxma = plsc->imclxmax;
  clpymi = plsc->imclymin;
  clpyma = plsc->imclymax;

  //  printf("clpxmi %d %d %d %d\n", clpxmi, clpxma, clpymi, clpyma);

  wcxmi = (clpxmi - pls->wpxoff)/pls->wpxscl;
  wcxma = (clpxma - pls->wpxoff)/pls->wpxscl;
  wcymi = (clpymi - pls->wpyoff)/pls->wpyscl;
  wcyma = (clpyma - pls->wpyoff)/pls->wpyscl;

  npts = plsc->dev_nptsX*plsc->dev_nptsY;

  nx = pls->dev_nptsX;
  ny = pls->dev_nptsY;

  imageXmin = pls->dev_ix[0];
  imageYmin = pls->dev_iy[0];
  imageXmax = pls->dev_ix[nx*ny-1];
  imageYmax = pls->dev_iy[nx*ny-1];

  //  printf("imageXmin %d %d %d %d\n", imageXmin, imageXmax, imageYmin, imageYmax);

  if (clpxmi > imageXmin) {
    imageX0 = dev->xScale * clpxmi+1;
    image_kx_start = (int)wcxmi;
  } else {
    imageX0 = dev->xScale * imageXmin+1;
    image_kx_start = 0;
  }

  if (clpxma < imageXmax) {
    imageWX = dev->xScale*clpxma-imageX0;
    image_kx_end = (int)wcxma;
    image_wkx =  image_kx_end-image_kx_start+1;
  } else {
    imageWX = dev->xScale * imageXmax - imageX0;
    image_kx_end = image_kx_start+nx;
    image_wkx = nx;
  }

  if (clpymi > imageYmin) {
    imageY0 = dev->yScale*(PIXELS_Y-clpyma)+1;
    image_ky_start = ny - 1 - (int)wcyma;
  } else {
    imageY0 = dev->yScale * (PIXELS_Y - imageYmax)+1;
    image_ky_start = 0;
  }

  if (clpyma < imageYmax) {
    imageWY = dev->yScale*(PIXELS_Y-clpymi)-imageY0;
    image_ky_end = ny -1 - (int)(wcymi);
    image_wky = image_ky_end-image_ky_start+1;
  } else {
    imageWY = dev->yScale * (PIXELS_Y - imageYmin) - imageY0;
    image_ky_end = ny - 1 - image_ky_start;
    image_wky = ny;
  }

  //  printf("imageX0 %d %d %d %d\n", imageX0, imageY0, imageWX, imageWY);
  //  printf("kx %d %d %d %d\n", image_kx_start, image_kx_end, image_ky_start, image_ky_end);
  //  printf("Before malloc... %d %d \n", nx, ny);
  byteArray = (BYTE*)malloc(nx*ny*sizeof(BYTE)*4);
  //  printf("After malloc...\n");

  for (ix=0; ix<nx; ix++)
    if ((ix >= image_kx_start) || (ix <= image_kx_end))
      {
	ptr1 = 4*ix;
	for (iy=0; iy<ny; iy++)
	  if ((iy >= image_ky_start) || (iy <= image_ky_end))
	  {
	    icol1 = pls->dev_z[ix*(ny-1)+iy]/65535.*pls->ncol1;
	    icol1 = MIN(icol1, pls->ncol1-1);
	    ptr2 = ptr1+4*(ny-iy-1)*nx;
	    //	    printf("%d  ", ptr2);
	    *(BYTE*)(byteArray+sizeof(BYTE)*ptr2++) = pls->cmap1[icol1].b;
	    *(BYTE*)(byteArray+sizeof(BYTE)*ptr2++) = pls->cmap1[icol1].g;
	    *(BYTE*)(byteArray+sizeof(BYTE)*ptr2++) = pls->cmap1[icol1].r;
	    *(BYTE*)(byteArray+sizeof(BYTE)*ptr2) = 255;
	  }
      }
  //  printf("Before CreateCompatibleBitmap...\n");
  bitmap = CreateCompatibleBitmap(dev->hdc, nx, ny);
  SetBitmapBits(bitmap, 4*npts, (const void*)byteArray);

  //  printf("Before CreateCompatibleDC...\n");
  hdcMemory = CreateCompatibleDC(dev->hdc);
  bitmapOld = (HBITMAP)SelectObject(hdcMemory, bitmap);
  SetStretchBltMode(dev->hdc, HALFTONE);
  //  printf("%d %d %d %d %d %d %d %d\n",imageX0, imageY0, imageWX, imageWY, image_kx_start, image_ky_start, image_wkx, image_wky);
  StretchBlt(dev->hdc, imageX0, imageY0, imageWX, imageWY, hdcMemory, image_kx_start, image_ky_start, image_wkx, image_wky, SRCCOPY);
  SelectObject(hdcMemory, bitmapOld);
  DeleteObject(bitmap);
  ReleaseDC(dev->hwnd,hdcMemory);				
  free(byteArray);
}
예제 #28
0
/* Note that this also does the right thing for colored tiles. */
static int
win_ddb_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile,
      int x, int y, int w, int h, gx_color_index czero, gx_color_index cone,
		       int px, int py)
{
    fit_fill(dev, x, y, w, h);
    if (czero != gx_no_color_index && cone != gx_no_color_index) {
	fill_rect(x, y, w, h, czero);
	czero = gx_no_color_index;
    }
    if (tile->raster == bmWidthBytes && tile->size.y <= bmHeight &&
	(px | py) == 0 && cone != gx_no_color_index
	) {			/* We can do this much more efficiently */
	/* by using the internal algorithms of copy_mono */
	/* and gx_default_tile_rectangle. */
	int width = tile->size.x;
	int height = tile->size.y;
	int rwidth = tile->rep_width;
	int irx = ((rwidth & (rwidth - 1)) == 0 ?	/* power of 2 */
		   x & (rwidth - 1) :
		   x % rwidth);
	int ry = y % tile->rep_height;
	int icw = width - irx;
	int ch = height - ry;
	int ex = x + w, ey = y + h;
	int fex = ex - width, fey = ey - height;
	int cx, cy;

	select_brush((int)cone);

	if (tile->id != wdev->bm_id || tile->id == gx_no_bitmap_id) {
	    wdev->bm_id = tile->id;
	    SetBitmapBits(wdev->hbmmono,
			  (DWORD) (bmWidthBytes * tile->size.y),
			  (BYTE *) tile->data);
	}
#define copy_tile(srcx, srcy, tx, ty, tw, th)\
  BitBlt(wdev->hdcbit, tx, ty, tw, th, wdev->hdcmono, srcx, srcy, rop_write_at_1s)

	if (ch > h)
	    ch = h;
	for (cy = y;;) {
	    if (w <= icw)
		copy_tile(irx, ry, x, cy, w, ch);
	    else {
		copy_tile(irx, ry, x, cy, icw, ch);
		cx = x + icw;
		while (cx <= fex) {
		    copy_tile(0, ry, cx, cy, width, ch);
		    cx += width;
		}
		if (cx < ex) {
		    copy_tile(0, ry, cx, cy, ex - cx, ch);
		}
	    }
	    if ((cy += ch) >= ey)
		break;
	    ch = (cy > fey ? ey - cy : height);
	    ry = 0;
	}

	win_update((gx_device_win *) dev);
	return 0;
    }
    return gx_default_tile_rectangle(dev, tile, x, y, w, h, czero, cone, px, py);
}
예제 #29
0
void api::refreshScreen()
{
	SetBitmapBits(back_buffer, 4 * numPixels, data);
	SelectObject(DC_back_buffer, back_buffer);
	BitBlt(hDC, 0, 0, width, height, DC_back_buffer, 0, 0, SRCCOPY);
}
예제 #30
0
/*
 * See if finds a transparent background in image, and set its transparency
 * Return TRUE if found a transparent background
 */
BOOL MakeTransparentBkg(MCONTACT hContact, HBITMAP *hBitmap)
{
	int i, j;

	BITMAP bmp;
	GetObject(*hBitmap, sizeof(bmp), &bmp);
	int width = bmp.bmWidth;
	int height = bmp.bmHeight;
	int colorDiff = db_get_w(hContact, "ContactPhoto", "TranspBkgColorDiff", db_get_w(0, AVS_MODULE, "TranspBkgColorDiff", 10));

	// Min 5x5 to easy things in loop
	if (width <= 4 || height <= 4)
		return FALSE;

	DWORD dwLen = width * height * 4;
	BYTE *p = (BYTE *)malloc(dwLen);
	if (p == nullptr)
		return FALSE;

	HBITMAP hBmpTmp;
	if (bmp.bmBitsPixel == 32)
		hBmpTmp = *hBitmap;
	else // Convert to 32 bpp
		hBmpTmp = CopyBitmapTo32(*hBitmap);

	GetBitmapBits(hBmpTmp, dwLen, p);

	// **** Get corner colors

	// Top left
	BYTE colors[8][3];
	BOOL foundBkg[8];
	if (!GetColorForPoint(colorDiff, p, width, 0, 0, 0, 1, 1, 0, &foundBkg[0], &colors[0])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Top center
	if (!GetColorForPoint(colorDiff, p, width, width / 2, 0, width / 2 - 1, 0, width / 2 + 1, 0, &foundBkg[1], &colors[1])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Top Right
	if (!GetColorForPoint(colorDiff, p, width,
		width - 1, 0, width - 1, 1, width - 2, 0, &foundBkg[2], &colors[2])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Center left
	if (!GetColorForPoint(colorDiff, p, width, 0, height / 2, 0, height / 2 - 1, 0, height / 2 + 1, &foundBkg[3], &colors[3])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Center left
	if (!GetColorForPoint(colorDiff, p, width, width - 1, height / 2, width - 1, height / 2 - 1, width - 1, height / 2 + 1, &foundBkg[4], &colors[4])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Bottom left
	if (!GetColorForPoint(colorDiff, p, width, 0, height - 1, 0, height - 2, 1, height - 1, &foundBkg[5], &colors[5])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Bottom center
	if (!GetColorForPoint(colorDiff, p, width, width / 2, height - 1, width / 2 - 1, height - 1, width / 2 + 1, height - 1, &foundBkg[6], &colors[6])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Bottom Right
	if (!GetColorForPoint(colorDiff, p, width, width - 1, height - 1, width - 1, height - 2, width - 2, height - 1, &foundBkg[7], &colors[7])) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// **** X corners have to have the same color

	int count = 0;
	for (i = 0; i < 8; i++)
		if (foundBkg[i])
			count++;

	if (count < db_get_w(hContact, "ContactPhoto", "TranspBkgNumPoints", db_get_w(0, AVS_MODULE, "TranspBkgNumPoints", 5))) {
		if (hBmpTmp != *hBitmap)
			DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Ok, X corners at least have a color, lets compare then
	int maxCount = 0, selectedColor = 0;
	for (i = 0; i < 8; i++) {
		if (foundBkg[i]) {
			count = 0;

			for (j = 0; j < 8; j++) {
				if (foundBkg[j] && ColorsAreTheSame(colorDiff, (BYTE *)&colors[i], (BYTE *)&colors[j]))
					count++;
			}

			if (count > maxCount) {
				maxCount = count;
				selectedColor = i;
			}
		}
	}

	if (maxCount < db_get_w(hContact, "ContactPhoto", "TranspBkgNumPoints",
		db_get_w(0, AVS_MODULE, "TranspBkgNumPoints", 5))) {
		// Not enought corners with the same color
		if (hBmpTmp != *hBitmap) DeleteObject(hBmpTmp);
		free(p);
		return FALSE;
	}

	// Get bkg color as mean of colors
	{
		int bkgColor[3];
		bkgColor[0] = 0;
		bkgColor[1] = 0;
		bkgColor[2] = 0;
		for (i = 0; i < 8; i++) {
			if (foundBkg[i] && ColorsAreTheSame(colorDiff, (BYTE *)&colors[i], (BYTE *)&colors[selectedColor])) {
				bkgColor[0] += colors[i][0];
				bkgColor[1] += colors[i][1];
				bkgColor[2] += colors[i][2];
			}
		}
		bkgColor[0] /= maxCount;
		bkgColor[1] /= maxCount;
		bkgColor[2] /= maxCount;

		colors[selectedColor][0] = bkgColor[0];
		colors[selectedColor][1] = bkgColor[1];
		colors[selectedColor][2] = bkgColor[2];
	}

	// **** Set alpha for the background color, from the borders
	if (hBmpTmp != *hBitmap) {
		DeleteObject(*hBitmap);

		*hBitmap = hBmpTmp;

		GetObject(*hBitmap, sizeof(bmp), &bmp);
		GetBitmapBits(*hBitmap, dwLen, p);
	}

	// Set alpha from borders
	bool transpProportional = (db_get_b(NULL, AVS_MODULE, "MakeTransparencyProportionalToColorDiff", 0) != 0);

	int *stack = (int *)malloc(width * height * 2 * sizeof(int));
	if (stack == nullptr) {
		free(p);
		return FALSE;
	}

	// Put four corners
	int topPos = 0;
	AddToStack(stack, &topPos, 0, 0);
	AddToStack(stack, &topPos, width / 2, 0);
	AddToStack(stack, &topPos, width - 1, 0);
	AddToStack(stack, &topPos, 0, height / 2);
	AddToStack(stack, &topPos, width - 1, height / 2);
	AddToStack(stack, &topPos, 0, height - 1);
	AddToStack(stack, &topPos, width / 2, height - 1);
	AddToStack(stack, &topPos, width - 1, height - 1);

	int curPos = 0;
	while (curPos < topPos) {
		// Get pos
		int x = stack[curPos]; curPos++;
		int y = stack[curPos]; curPos++;

		// Get pixel
		BYTE *px1 = GET_PIXEL(p, x, y);

		// It won't change the transparency if one exists
		// (This avoid an endless loop too)
		// Not using == 255 because some MSN bmps have 254 in some positions
		if (px1[3] >= 253) {
			if (ColorsAreTheSame(colorDiff, px1, (BYTE *)&colors[selectedColor])) {
				px1[3] = (transpProportional) ? min(252,
					(abs(px1[0] - colors[selectedColor][0])
					+ abs(px1[1] - colors[selectedColor][1])
					+ abs(px1[2] - colors[selectedColor][2])) / 3) : 0;

				// Add 4 neighbours
				if (x + 1 < width)
					AddToStack(stack, &topPos, x + 1, y);

				if (x - 1 >= 0)
					AddToStack(stack, &topPos, x - 1, y);

				if (y + 1 < height)
					AddToStack(stack, &topPos, x, y + 1);

				if (y - 1 >= 0)
					AddToStack(stack, &topPos, x, y - 1);
			}
		}
	}

	free(stack);

	SetBitmapBits(*hBitmap, dwLen, p);
	free(p);
	return TRUE;
}