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

📄 bmpprocessor.cpp

📁 Resource editor base speadrum Chinese mobile
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// BmpProcessor.cpp: implementation of the CBmpProcessor class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ResourceEditor.h"
#include "BmpProcessor.h"
#include "Converter.h"

//#include "dal_img.h"
//#include "Img_port.h"

#define IMG_SUCCESS 0
extern "C" void  IMG_xFreeMem(void *ptr);
extern "C" uint32 IMG_CompressBmp(
					   const uint8 *bmpfile_stream,
					   uint8 **code_stream,
					   uint32 *codelen
					   );
extern "C" uint32 IMG_CompressMovie(
						 const char *dirname,
						 uint32 framenum,
						 uint8 **code_stream,
						 uint32 *codelen,
						 uint32 same_color888	
						 );
extern "C" uint32 IMG_ExtractBmp(
					  const uint8* code_stream,
					  uint8 **bmpfile_stream,
					  uint32 *filelen
					  );
extern "C" uint32 IMG_ExtractMovie(
						const uint8* code_stream,
						char *dirname,
						uint32 *framenum
						);
extern "C" uint32 IMG_ExtractMovieByIdx(
							 const uint8* code_stream,
							 uint8 ** pBmp,
							 uint16 index
							 );
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBmpProcessor::CBmpProcessor()
{
    *m_szErrMsg = 0;
}

CBmpProcessor::~CBmpProcessor()
{

}

BOOL CBmpProcessor::LoadBmpFile( LPCTSTR pszFileName, LPBYTE * pBmpStream, 
                                 int * pSize /* = NULL */, BOOL b565 /* = TRUE */ )
{
    _ASSERTE( pszFileName != NULL );
    _ASSERTE( pBmpStream != NULL );

    HANDLE hFile = ::CreateFile( pszFileName, GENERIC_READ, FILE_SHARE_READ,
                                 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                                 NULL );
    if( hFile == INVALID_HANDLE_VALUE )
    {
        _stprintf(m_szErrMsg, _T("The file '%s' not exist!"), pszFileName);
        return FALSE;
    }

    int nSize = (int)GetFileSize(hFile, NULL);
    if( nSize < sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) )
    {
        ::CloseHandle(hFile);
        _stprintf(m_szErrMsg, _T("The file '%s' size is too little!"), pszFileName);
        return FALSE;
    }

    LPBYTE pBmp = (LPBYTE)malloc(nSize);
	//memset( pBmp,0xff,nSize );
    if( NULL == pBmp )   
    {
        ::CloseHandle(hFile);
        return FALSE;
    }

    DWORD dwRead = 0;
    if( !ReadFile(hFile, pBmp, nSize, &dwRead, NULL) || nSize != (int)dwRead )
    {
        TRACE1("ReadFile %s error!\r\n", pszFileName);
        _stprintf(m_szErrMsg, _T("ReadFile '%s' error!"), pszFileName);
        ::CloseHandle(hFile);
        return FALSE;
    }
    ::CloseHandle(hFile);

    PBITMAPFILEHEADER pbfh = (PBITMAPFILEHEADER)pBmp;
    if( pbfh->bfType != 0x4d42 )
    {
        free(pBmp);
        _stprintf(m_szErrMsg, _T("The file '%s' is incorrect bitmap file!"), pszFileName);
        return FALSE;
    }
	// @ Hongliang Xin 2006-8-11
	if(pbfh->bfSize != (unsigned int)nSize)
	{
		pbfh->bfSize = (unsigned int)nSize;
	}
    PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)(pbfh + 1);
   
    BOOL bRet = TRUE;
    if( !b565 )
    {
        if( pbih->biBitCount != 24 && pbih->biBitCount != 16 )
        {
            free(pBmp);
            _tcscpy(m_szErrMsg, _T("Currently, we only support 24 or 16 bit") );
            return FALSE;
        }
        *pBmpStream = pBmp;
    }
    else
    {
        if( pbih->biBitCount == 24 )
        {
            LPBYTE p565Bmp = NULL;
            bRet = Convert24To565Stream(pBmp, p565Bmp, nSize);
            if( bRet )
            {
                *pBmpStream = p565Bmp;
                free(pBmp);
            }
        }
        else if( pbih->biBitCount == 16 )
        {
            LPDWORD pRedMask = (LPDWORD)(pbih + 1);
            if( *pRedMask == 0xF800 )
            {
                _ASSERTE( *(pRedMask+1) == 0x07E0 );
                _ASSERTE( *(pRedMask+2) == 0x001F );

                int nDelta = pbfh->bfOffBits - sizeof(BITMAPFILEHEADER) - 
                             sizeof(BITMAPINFOHEADER) - 3 * sizeof(DWORD);
                if( nDelta > 0 )
                {
                    pbfh->bfSize -= nDelta;
                    LPBYTE pBmpData = (LPBYTE)(pBmp + pbfh->bfOffBits);
                    pbfh->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
                                      3 * sizeof(DWORD);
                    pbih->biSize    = sizeof(BITMAPINFOHEADER);
                    MoveMemory( pBmp + pbfh->bfOffBits, pBmpData, pbfh->bfSize - pbfh->bfOffBits );
					
					LPBYTE pBmpFile = new BYTE[pbfh->bfSize];
					if(pBmpFile == NULL)
					{
						free(pBmp);
						return FALSE;
					}
					CopyMemory(pBmpFile,pBmp,pbfh->bfSize);
					free(pBmp);
					pBmp = pBmpFile;
                }
                else
                {
                    pbih->biSizeImage = pbfh->bfSize - pbfh->bfOffBits;//
                }
                *pBmpStream = pBmp;   
            }
            else
            {
                LPBYTE p565Bmp = NULL;
                bRet = Convert555To565Stream(pBmp, p565Bmp, nSize);
                if( bRet )
                {
                    *pBmpStream = p565Bmp;
                    free(pBmp);
                }
            }
        }
        else
        {
            free(pBmp);
            _tcscpy(m_szErrMsg, _T("Currently, we only support 24 or 16 bit") );
            return FALSE;
        }

    }

    if( pSize != NULL )
        *pSize = nSize;
    
    return bRet;
}

CSize CBmpProcessor::GetBmpSize( LPBYTE pBmp )
{
    _ASSERTE( pBmp != NULL );

    PBITMAPFILEHEADER pbfh = (PBITMAPFILEHEADER)pBmp;
    _ASSERTE(pbfh->bfType == 0x4d42);

    PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)(pbfh + 1);

    return CSize(pbih->biWidth, pbih->biHeight);
}

CSize CBmpProcessor::GetMovieSize( LPBYTE pMovie )
{
    _ASSERTE( pMovie != NULL );

    PBITMAPFILEHEADER pbfh = (PBITMAPFILEHEADER)pMovie;
    _ASSERTE(pbfh->bfType == 0x4D56); // "MV"

    PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)(pbfh + 1);

    return CSize(pbih->biWidth, pbih->biHeight);
}

HBITMAP CBmpProcessor::CreateBitmap( LPBYTE pBmpStream )
{
    _ASSERTE( NULL != pBmpStream );

    PBITMAPFILEHEADER pbfh = (PBITMAPFILEHEADER)pBmpStream;
    
    PBITMAPINFO pbi = (PBITMAPINFO)(pbfh + 1);
    
    pBmpStream += pbfh->bfOffBits;

    LPBYTE pBits = NULL;
    HBITMAP hBmp = ::CreateDIBSection(NULL, pbi, DIB_RGB_COLORS, (LPVOID *)&pBits, NULL, 0 );

    // 注意文件中数据的内容长度可能大于实际数据的长度
    int nSize = ((pbi->bmiHeader.biWidth * pbi->bmiHeader.biBitCount + 31) &~31) / 8;;
    nSize *= pbi->bmiHeader.biHeight;

    memcpy(pBits, pBmpStream, nSize);
    
    return hBmp;
}

HBITMAP CBmpProcessor::CreateBitmap( LPCTSTR pszFileName )
{
    _ASSERTE( pszFileName != NULL );

    LPBYTE  pBmp = NULL;
    HBITMAP hBmp = NULL;

    if( LoadBmpFile(pszFileName, &pBmp) )
    {
        hBmp = CreateBitmap(pBmp);
        free(pBmp);
    }
    
    return hBmp;
}

void CBmpProcessor::DeleteBitmap( HBITMAP hBmp )
{
    _ASSERTE( hBmp != NULL );

    ::DeleteObject(hBmp);
}

// 将原始位图数据流转换为16位565格式的数据流(这里的数据流指完整的位图文件内容)
// 如果pBmp就是16位565格式的,直接返回此指针,否则会产生新的内存块
BOOL CBmpProcessor::Convert24To565Stream( LPBYTE p24Bmp, LPBYTE &p16Bmp, int &nSize )
{
    _ASSERTE( p24Bmp != NULL );

    PBITMAPFILEHEADER p24bfh = (PBITMAPFILEHEADER)p24Bmp;
    _ASSERTE(p24bfh->bfType == 0x4d42);

    PBITMAPINFOHEADER p24bih = (PBITMAPINFOHEADER)(p24bfh + 1);
    _ASSERTE( p24bih->biBitCount == 24 );

    LPBYTE p24Data = p24Bmp + p24bfh->bfOffBits;

    int nWidth     = p24bih->biWidth;
    int nHeight    = p24bih->biHeight;
    int n24RowSize = ( (nWidth * 24 + 31) & ~31 ) / 8;
    int n16RowSize = ( (nWidth * 16 + 31) & ~31 ) / 8;

    nSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
            3 * sizeof(DWORD) + n16RowSize * nHeight;

    p16Bmp = (LPBYTE)malloc(nSize);
    if( NULL == p16Bmp )
    {
        nSize = 0;
        return FALSE;
    }
    memset( p16Bmp, 0, nSize );

    PBITMAPFILEHEADER p16bfh = (PBITMAPFILEHEADER)p16Bmp;
    memcpy(p16bfh, p24bfh, sizeof(BITMAPFILEHEADER));
    p16bfh->bfOffBits = nSize - n16RowSize * nHeight;
    p16bfh->bfSize    = nSize;

    PBITMAPINFOHEADER p16bih = (PBITMAPINFOHEADER)(p16bfh + 1);
    memcpy(p16bih, p24bih, sizeof(BITMAPINFOHEADER));
    p16bih->biSize        = sizeof(BITMAPINFOHEADER);
    p16bih->biBitCount    = 16;
    p16bih->biCompression = BI_BITFIELDS;
    p16bih->biSizeImage   = 0;
    p16bih->biClrUsed     = 0;

    LPDWORD pRedMask = (LPDWORD)(p16bih + 1);
    *pRedMask = 0xF800;

    LPDWORD pGreenMask = pRedMask + 1;
    *pGreenMask = 0x07E0;

    LPDWORD pBlueMask = pGreenMask + 1;
    *pBlueMask = 0x001F;

    LPBYTE p16Data = (LPBYTE)(pBlueMask + 1);
    
    for( int i = 0; i < nHeight; ++i )
    {
        Bmp24To565(p24Data + i * n24RowSize, nWidth * 3, (LPWORD)p16Data, n16RowSize);

        p16Data += n16RowSize;
    }
    
    // 调试用
    //FILE * pfile = fopen("c:\\24to565.bmp", "wb");
    //fwrite(p16Bmp, 1, nSize, pfile);
    //fclose(pfile);

    return TRUE;
}

void CBmpProcessor::Bmp24To565(LPBYTE p888, int n888Size, LPWORD p565, int n565Size)
{
	_ASSERTE( p888 != NULL && p565 != NULL );
	_ASSERTE( n888Size * 2 / 3 <= n565Size );

	WORD wValue;
	for(int i = 0; i < (int)n888Size; i += 3)
	{
		wValue = *p888 >> 3;
        *p565  = wValue;
		p888++;
	
		wValue = *p888 >> 2;
		wValue <<= 5;
		*p565 |= wValue;
		p888++;
	
		wValue = *p888 >> 3;
		wValue <<= 11;
		*p565 |= wValue;
		p888++;

		p565++;
	}
}

BOOL CBmpProcessor::Convert555To565Stream( LPBYTE p555Bmp, LPBYTE &p565Bmp, int &nSize )
{
    _ASSERTE( p555Bmp != NULL );

    PBITMAPFILEHEADER p555bfh = (PBITMAPFILEHEADER)p555Bmp;
    _ASSERTE(p555bfh->bfType == 0x4d42);

    PBITMAPINFOHEADER p555bih = (PBITMAPINFOHEADER)(p555bfh + 1);
    _ASSERTE( p555bih->biBitCount == 16 );

    LPWORD p555Data = (LPWORD)(p555Bmp + p555bfh->bfOffBits);

    int nWidth     = p555bih->biWidth;
    int nHeight    = p555bih->biHeight;
    int n16RowSize = ( (nWidth * 16 + 31) & ~31 ) / 8;

    nSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
            3 * sizeof(DWORD) + n16RowSize * nHeight;

    p565Bmp = (LPBYTE)malloc(nSize);

⌨️ 快捷键说明

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