⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmp2ovr.cpp

📁 在嵌入式 WINCE 中实现 OSD 功能
💻 CPP
字号:
#include <windows.h>
#include <ddraw.h>

DWORD GetBMPPixel( int x, int y, BYTE *pDIBBits, BITMAPINFO *pbmInfo )
{
	BITMAPINFOHEADER *pbmiHeader = &(pbmInfo->bmiHeader);
	RGBQUAD *pRgb = (RGBQUAD *)pbmInfo->bmiColors;
	RGBQUAD rgbQuad;
	DWORD	dwStride;

//	RETAILMSG(1, (TEXT("%d, %d, 0x%08X\r\n"), x, y, (DWORD)pDIBBits ));

	dwStride = ((((pbmiHeader->biWidth * pbmiHeader->biBitCount)+7)/8) + 3) & 0xFFFFFFFC;	// DWORD align
	pDIBBits += dwStride * (pbmiHeader->biHeight - (y+1));
	
	switch( pbmiHeader->biBitCount )
	{
	case  1 :
		pDIBBits += (x>>3);
		return *(DWORD *)(pRgb + ((*pDIBBits>>(7 - x%8)) & 0x01));
	case  2 :
		pDIBBits += (x>>2);
		return *(DWORD *)(pRgb + ((*pDIBBits>>((3 - x%4)<<1)) & 0x03));
	case  4 :
		pDIBBits += (x>>1);
		return *(DWORD *)(pRgb + ((*pDIBBits>>((1 - x%2)<<2)) & 0x0F));
	case  8 :
		pDIBBits += x;
		return *(DWORD *)(pRgb + *pDIBBits);
	case 16 :
		pDIBBits += (x<<1);
		rgbQuad.rgbBlue		= (BYTE)((*(WORD *)pDIBBits & 0x001F)<<3);
		rgbQuad.rgbGreen	= (BYTE)((*(WORD *)pDIBBits & 0x03E0)>>2);
		rgbQuad.rgbRed		= (BYTE)((*(WORD *)pDIBBits & 0x7C00)>>7);
		rgbQuad.rgbReserved = 0;
		return *(DWORD *)&rgbQuad;
	case 24 :
		pDIBBits += x*3;
//		RETAILMSG(1, (TEXT("-> 0x%08X\r\n"), (DWORD)pDIBBits ));
		rgbQuad.rgbBlue		= *pDIBBits++;
		rgbQuad.rgbGreen	= *pDIBBits++;
		rgbQuad.rgbRed		= *pDIBBits++;
		rgbQuad.rgbReserved = 0;
		return *(DWORD *)&rgbQuad;
	case 32 :
		pDIBBits += (x<<2);
		rgbQuad.rgbBlue		= *pDIBBits++;
		rgbQuad.rgbGreen	= *pDIBBits++;
		rgbQuad.rgbRed		= *pDIBBits++;
		rgbQuad.rgbReserved = 0;
		return *(DWORD *)&rgbQuad;
	default :
		ERRORMSG(1, (TEXT("GetBMPPixel : Unknown bpp = %d\r\n"), pbmiHeader->biBitCount ));
		return 0;
	}
}

HRESULT LoadBMPToOverlay
( 
	LPTSTR 					pszFilename, 
	LPDIRECTDRAW4 			pDD4, 
	LPDIRECTDRAWSURFACE4 	*lplpDDSurface, 
	int 					*pWidth, 
	int 					*pHeight 
)
{
    DDSURFACEDESC2			ddsd;
	LPDIRECTDRAWSURFACE4	lpDDSurface = NULL;
	
	BYTE *pDIB 		= NULL;
	BYTE *pDIBBits 	= NULL;
	BITMAPFILEHEADER	bmfHeader;	
	BITMAPINFO 			*pbmInfo = NULL;

	HANDLE 	hFile = INVALID_HANDLE_VALUE;
	DWORD 	dwSizeRead;          	
	DWORD 	dwFileSize;

	DWORD 	RGBData;
	int		R, G, B, Y0, Y1, U, V;
	BYTE	*pSurf;
	int		i, j;

	BOOL 	b;
	HRESULT	hr = S_OK;

	*lplpDDSurface = NULL;

	//--------------------------------------------------------------------------
	// Load a bitmap file
	//--------------------------------------------------------------------------
	// Open file
	hFile = ::CreateFile(pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		ERRORMSG(1, (TEXT("CreateFile Failed\r\n")));
        hr = E_FAIL;
		goto LoadBMPToOverlay_Failed;
	}

	// Read file header
	b = ::ReadFile(hFile, (LPVOID)&bmfHeader, sizeof(bmfHeader),
		&dwSizeRead, NULL);
	if (b == FALSE)
	{
		ERRORMSG(1, (TEXT("ReadFile : BITMAPFILEHEADER Failed\r\n")));
        hr = E_FAIL;
		goto LoadBMPToOverlay_Failed;
	}
	
	// File type should be 'BM'
	if (bmfHeader.bfType != ((WORD)('M'<<8) | 'B'))
	{
		ERRORMSG(1, (TEXT("Type is not BM\r\n")));
        hr = E_FAIL;
		goto LoadBMPToOverlay_Failed;
	}

	// Get file size
	dwFileSize = ::GetFileSize(hFile, NULL);

	// Allocate memory for DIB
	pDIB = new BYTE[dwFileSize];
	if( pDIB == NULL )
	{
		ERRORMSG(1, (TEXT("OUTOFMEMORY : %d\r\n"), dwFileSize ));
		hr = E_OUTOFMEMORY;
		goto LoadBMPToOverlay_Failed;
	}

	// Read the other data
	b = ::ReadFile(hFile, pDIB, dwFileSize - sizeof(bmfHeader),
		&dwSizeRead, NULL);
	if (dwSizeRead != dwFileSize - sizeof(bmfHeader))
	{
		ERRORMSG(1, (TEXT("ReadFile : BITMAPINFO & Data Failed\r\n")));
		hr = E_FAIL;
		goto LoadBMPToOverlay_Failed;
	}

	// Initialize the bitmap info pointer
	pbmInfo 	= (BITMAPINFO *)pDIB;
	pDIBBits 	= (LPBYTE)((DWORD)pDIB + bmfHeader.bfOffBits - sizeof(BITMAPFILEHEADER));

	// Close file
	b = ::CloseHandle(hFile);
	if (b == FALSE)
	{
		ERRORMSG(1, (TEXT("Error to close the file handle!\r\n")));
		hr = E_FAIL;
		goto LoadBMPToOverlay_Failed;
	}

	hFile = INVALID_HANDLE_VALUE;
	
	if( pbmInfo->bmiHeader.biWidth & 1 )	
	{
		ERRORMSG(1, (TEXT("Image must have even width = %d\r\n"), pbmInfo->bmiHeader.biWidth ));
		hr = E_FAIL;
		goto LoadBMPToOverlay_Failed;
	}

	RETAILMSG(1, (TEXT("bfOffBits = %d\r\n"), 		bmfHeader.bfOffBits ));
	RETAILMSG(1, (TEXT("biSize = %d\r\n"),         	pbmInfo->bmiHeader.biSize ));    
	RETAILMSG(1, (TEXT("biWidth = %d\r\n"),        	pbmInfo->bmiHeader.biWidth ));   
	RETAILMSG(1, (TEXT("biHeight = %d\r\n"),       	pbmInfo->bmiHeader.biHeight ));   
	RETAILMSG(1, (TEXT("biPlanes = %d\r\n"),       	pbmInfo->bmiHeader.biPlanes )); 
	RETAILMSG(1, (TEXT("biBitCount = %d\r\n"),     	pbmInfo->bmiHeader.biBitCount ));
	RETAILMSG(1, (TEXT("biCompression = %d\r\n"),  	pbmInfo->bmiHeader.biCompression ));
	RETAILMSG(1, (TEXT("biSizeImage = %d\r\n"),    	pbmInfo->bmiHeader.biSizeImage ));
	RETAILMSG(1, (TEXT("biXPelsPerMeter = %d\r\n"),	pbmInfo->bmiHeader.biXPelsPerMeter ));
	RETAILMSG(1, (TEXT("biYPelsPerMeter = %d\r\n"),	pbmInfo->bmiHeader.biYPelsPerMeter ));
	RETAILMSG(1, (TEXT("biClrUsed = %d\r\n"),      	pbmInfo->bmiHeader.biClrUsed )); 
	RETAILMSG(1, (TEXT("biClrImportant = %d\r\n"), 	pbmInfo->bmiHeader.biClrImportant ));
	
	//--------------------------------------------------------------------------
	// Allocate Surface
	//--------------------------------------------------------------------------
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize 					= sizeof(ddsd);
	ddsd.dwFlags 					= DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; 
	ddsd.ddsCaps.dwCaps 			= DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; 
	ddsd.dwWidth 					= pbmInfo->bmiHeader.biWidth;
	ddsd.dwHeight 					= pbmInfo->bmiHeader.biHeight;
	ddsd.ddpfPixelFormat.dwSize		= sizeof(DDPIXELFORMAT); 
	ddsd.ddpfPixelFormat.dwFlags	= DDPF_FOURCC;
	ddsd.ddpfPixelFormat.dwFourCC	= MAKEFOURCC('Y','U','Y','2');
	
	hr = pDD4->CreateSurface(&ddsd, &lpDDSurface, NULL); 
	if( hr != DD_OK ) 
	{ 
		ERRORMSG(1, (TEXT("CreateSurface FAILED.\r\n")));
		goto LoadBMPToOverlay_Failed;
	} 

	hr = lpDDSurface->Lock( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL );
	if( FAILED(hr) )
	{
    	ERRORMSG(1, (TEXT("Surface Lock Failed = 0x%08X\r\n"), hr ));
    	goto LoadBMPToOverlay_Failed;
	}
	
	RETAILMSG(1, (TEXT("Surface Buffer = 0x%08X\r\n"), (DWORD)ddsd.lpSurface ));
	pSurf = (BYTE *)ddsd.lpSurface;

	//--------------------------------------------------------------------------
	// Copy bitmap data to overlay surface
	//--------------------------------------------------------------------------
	for( j=0 ; j<pbmInfo->bmiHeader.biHeight ; j++ )
	{
		for( i=0 ; i<pbmInfo->bmiHeader.biWidth ; i+=2 )
		{
			RGBData = GetBMPPixel( i, j, pDIBBits, pbmInfo );

			R = (int)(((RGBQUAD *)&RGBData)->rgbRed);
			G = (int)(((RGBQUAD *)&RGBData)->rgbGreen);
			B = (int)(((RGBQUAD *)&RGBData)->rgbBlue);
			
			Y0 = ((  66 * R + 129 * G +  25 * B + 128) >> 8) +  16;
			U  = (( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128;
			
			RGBData = GetBMPPixel( i+1, j, pDIBBits, pbmInfo );

			R = (int)(((RGBQUAD *)&RGBData)->rgbRed);
			G = (int)(((RGBQUAD *)&RGBData)->rgbGreen);
			B = (int)(((RGBQUAD *)&RGBData)->rgbBlue);

			Y1 = ((  66 * R + 129 * G +  25 * B + 128) >> 8) +  16;
			V  = (( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128;

			*(pSurf++) = (BYTE)Y0;
			*(pSurf++) = (BYTE)U;
			*(pSurf++) = (BYTE)Y1;
			*(pSurf++) = (BYTE)V;
		}
	}

	hr = lpDDSurface->Unlock( NULL );
	if( FAILED(hr) )
	{
    	ERRORMSG(1, (TEXT("Surface Unlock Failed = 0x%08X\r\n"), hr ));
    	goto LoadBMPToOverlay_Failed;
	}

	*lplpDDSurface 	= lpDDSurface;
	*pWidth			= pbmInfo->bmiHeader.biWidth;
	*pHeight		= pbmInfo->bmiHeader.biHeight;

	ASSERT( pDIB != NULL );				delete pDIB;

	return S_OK;

LoadBMPToOverlay_Failed :
	if( hFile != INVALID_HANDLE_VALUE )	::CloseHandle(hFile);
	if( pDIB != NULL )					delete pDIB;
	if( lpDDSurface != NULL )			lpDDSurface->Release();

	return hr;	
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -