📄 bmpprocessor.cpp
字号:
if( NULL == p565Bmp )
{
nSize = 0;
return FALSE;
}
memset( p565Bmp, 0, nSize );
//hongliang.xin 2006-11-13
PBITMAPFILEHEADER p565bfh = (PBITMAPFILEHEADER)p565Bmp;
memcpy(p565bfh, p555bfh, sizeof(BITMAPFILEHEADER));
p565bfh->bfOffBits = nSize - n16RowSize * nHeight;
p565bfh->bfSize = nSize;
PBITMAPINFOHEADER p565bih = (PBITMAPINFOHEADER)(p565bfh + 1);
memcpy(p565bih, p555bih, sizeof(BITMAPINFOHEADER));
p565bih->biSize = sizeof(BITMAPINFOHEADER);
p565bih->biBitCount = 16;
p565bih->biCompression = BI_BITFIELDS;
p565bih->biSizeImage = 0;
p565bih->biClrUsed = 0;
LPDWORD pRedMask = (LPDWORD)(p565bih + 1);
*pRedMask = 0xF800;
LPDWORD pGreenMask = pRedMask + 1;
*pGreenMask = 0x07E0;
LPDWORD pBlueMask = pGreenMask + 1;
*pBlueMask = 0x001F;
LPWORD p565Data = (LPWORD)(pBlueMask + 1);
BYTE byBlue, byGreen, byRed;
int nCount = (n16RowSize / 2) * nHeight;
for( int i = 0; i < nCount; ++i, p555Data++, p565Data++ )
{
byBlue = (BYTE)(*p555Data >> 10);
byGreen = (BYTE)(*p555Data >> 5);
byRed = (BYTE)(*p555Data);
*p565Data = (WORD)(byBlue << 11);
*p565Data |= (WORD)(byGreen << 6);
*p565Data |= (WORD)(byRed);
}
// 调试用
//FILE * pfile = fopen("c:\\555to565.bmp", "wb");
//fwrite(p16Bmp, 1, nSize, pfile);
//fclose(pfile);
return TRUE;
}
BOOL CBmpProcessor::Convert16To24Stream( LPBYTE p16Bmp, LPBYTE & p24Bmp, int &nSize )
{
_ASSERTE( p16Bmp != NULL );
PBITMAPFILEHEADER p16bfh = (PBITMAPFILEHEADER)p16Bmp;
_ASSERTE(p16bfh->bfType == 0x4d42);
PBITMAPINFOHEADER p16bih = (PBITMAPINFOHEADER)(p16bfh + 1);
_ASSERTE( p16bih->biBitCount == 16 );
LPBYTE p16Data = p16Bmp + p16bfh->bfOffBits;
int nWidth = p16bih->biWidth;
int nHeight = p16bih->biHeight;
int n24RowSize = ( (nWidth * 24 + 31) & ~31 ) / 8;
int n16RowSize = ( (nWidth * 16 + 31) & ~31 ) / 8;
nSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + n24RowSize * nHeight;
p24Bmp = (LPBYTE)malloc( nSize );
if( NULL == p24Bmp )
return FALSE;
memset(p24Bmp, 0, nSize);
PBITMAPFILEHEADER p24bfh = (PBITMAPFILEHEADER)p24Bmp;
memcpy(p24bfh, p16bfh, sizeof(BITMAPFILEHEADER));
p24bfh->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
p24bfh->bfSize = nSize;
PBITMAPINFOHEADER p24bih = (PBITMAPINFOHEADER)(p24bfh + 1);
memcpy(p24bih, p16bih, sizeof(BITMAPINFOHEADER));
p24bih->biSize = sizeof(BITMAPINFOHEADER);
p24bih->biBitCount = 24;
p24bih->biCompression = BI_RGB;
p24bih->biSizeImage = 0;
p24bih->biClrUsed = 0;
LPBYTE p24Data = (LPBYTE)(p24bih + 1);
BOOL bBmpIs555 = FALSE;
if( p16bih->biCompression == BI_RGB )
{
bBmpIs555 = TRUE;
}
else if( p16bih->biCompression == BI_BITFIELDS )
{
LPDWORD pRedMask = (LPDWORD)(p16bih + 1);
if( *pRedMask == 0x7C00 )
bBmpIs555 = TRUE;
}
else
{
_ASSERTE( 0 );
}
for( int i = 0; i < nHeight; ++i )
{
Bmp16To24( (LPWORD)p16Data, nWidth, p24Data, n24RowSize, bBmpIs555 );
p16Data += n16RowSize;
p24Data += n24RowSize;
}
// 调试用
//FILE * pfile = fopen("c:\\out.bmp", "wb");
//fwrite(p24Bmp, 1, nSize, pfile);
//fclose(pfile);
return TRUE;
}
// 注意:此函数不考虑对齐的情况(用在只转换一行的情况下)
void CBmpProcessor::Bmp16To24( LPWORD p16Bmp, int nPixel, LPBYTE p24Bmp, int n24Size, BOOL bIs555 /* = TRUE */ )
{
_ASSERTE( p16Bmp != NULL && nPixel > 0 );
_ASSERTE( p24Bmp != NULL && nPixel * 3 <= n24Size );
memset( p24Bmp, 0, n24Size );
WORD wRMask = bIs555 ? 0x7C00 : 0xF800;
int nRRShift = bIs555 ? 10 : 11;
int nRLShift = 3;
WORD wGMask = bIs555 ? 0x03E0 : 0x07E0;
int nGRShift = 5;
int nGLShift = bIs555 ? 3 : 2;
WORD wBMask = 0x001F;
int nBLShift = 3;
for( int i = 0; i < nPixel; ++i, ++p16Bmp )
{
*(p24Bmp++) = (BYTE)( (wBMask & *p16Bmp) << nBLShift);
*(p24Bmp++) = (BYTE)( ((wGMask & *p16Bmp) >> nGRShift) << nGLShift);
*(p24Bmp++) = (BYTE)( ((wRMask & *p16Bmp) >> nRRShift) << nRLShift);
}
}
BOOL CBmpProcessor::CompressBmp( LPBYTE p565Bmp, LPBYTE &pCompressed, int &nCompressedSize )
{
_ASSERTE( p565Bmp != NULL );
if( IMG_CompressBmp( (uint8 *)p565Bmp, &pCompressed, (uint32 *)&nCompressedSize ) != IMG_SUCCESS )
{
IMG_xFreeMem(pCompressed);
_tcscpy(m_szErrMsg, _T("Compress bitmap fail!") );
return FALSE;
}
return TRUE;
}
void CBmpProcessor::ReleaseCompressedStream( LPBYTE pCompressed )
{
if( pCompressed != NULL )
{
IMG_xFreeMem(pCompressed);
}
}
BOOL CBmpProcessor::CompressMovie( LPCTSTR pszDirName, LPBYTE &pCompressed,
int &nCompressedSize, int &nNum, UINT nTransColor/* = 0*/ )
{
_ASSERTE( pszDirName != NULL );
int nFrameNum = 0;
if(!IsMovieValidate(pszDirName,&nFrameNum))
return FALSE;
nNum = nFrameNum;
//////////////////////////////////////////////////////
//备份
_TCHAR szPathTemp[_MAX_PATH];
::GetModuleFileName(NULL, szPathTemp, _MAX_PATH);
LPTSTR pFind = _tcsrchr(szPathTemp, _T('\\'));
_tcscpy( pFind + 1, _T("AnimTempDir") );
CString strTempDir = szPathTemp;
if(!CreateDirectory(strTempDir,NULL))
{
AfxMessageBox(IDS_E_BACKUP_ANIM_FAIL);
return FALSE;
}
CString strTempFile,strFile,strFormat;
WIN32_FIND_DATA wfd;
HANDLE hFind = INVALID_HANDLE_VALUE;
strFormat = nFrameNum > 9 ? _T("%s\\%02d.bmp") : _T("%s\\%d.bmp");
for( int i = 1; i <= nFrameNum ; ++i )
{
strFile.Format(strFormat, pszDirName, i);
hFind = ::FindFirstFile(strFile, &wfd);
if( INVALID_HANDLE_VALUE == hFind )
{
CString strMsg;
strMsg.Format(_T("%s not exist!"), strFile);
AfxMessageBox(strMsg);
return FALSE;
}
::FindClose(hFind);
//备份BMP文件,准备转换成16位BMP
strTempFile.Format(strFormat,strTempDir,i);
if(!CopyFile(strFile,strTempFile,FALSE))
{
AfxMessageBox(IDS_E_BACKUP_ANIM_FAIL);
return FALSE;
}
ForceConvertBmpFile(strTempFile);
}
//////////////////////////////////////////////////////
CString strFileName;
strFileName.Format(_T("%s\\"), strTempDir);
UINT nByte = WideCharToMultiByte(CP_ACP,0, (LPCTSTR)strFileName,-1,NULL,0,NULL,NULL);
char *pszFilePath = new char[nByte+1];
memset(pszFilePath,0,nByte+1);
WideCharToMultiByte(CP_ACP, 0, strFileName, -1, pszFilePath, nByte, NULL, NULL);
if( IMG_CompressMovie(pszFilePath, nFrameNum, &pCompressed, (uint32 *)&nCompressedSize,nTransColor) != IMG_SUCCESS )
{
IMG_xFreeMem(pCompressed);
_tcscpy(m_szErrMsg, _T("Compress movie fail!") );
TRACE0("CompressMovie fail!");
delete []pszFilePath;
pszFilePath = NULL;
DeleteDirectory(strTempDir);
return FALSE;
}
delete []pszFilePath;
pszFilePath = NULL;
DeleteDirectory(strTempDir);
return TRUE;
}
BOOL CBmpProcessor::UnCompressBmp( LPBYTE pCompressed, LPBYTE &pBmp, int &nSize )
{
_ASSERTE( pCompressed != NULL );
if( IMG_ExtractBmp((uint8 *)pCompressed, &pBmp, (uint32 *)&nSize) != IMG_SUCCESS )
{
IMG_xFreeMem(pBmp);
pBmp = (LPBYTE)malloc(nSize);
if( pBmp == NULL )
return FALSE;
memcpy(pBmp, pCompressed, nSize);
}
_ASSERTE( pBmp != NULL && nSize > 0 );
return TRUE;
}
BOOL CBmpProcessor::UnCompressMovie( LPBYTE pMovie, LPCTSTR pszDirName )
{
_ASSERTE( pMovie != NULL && pszDirName != NULL );
if( !::CreateDirectory(pszDirName, NULL) )
{
if( GetLastError() != ERROR_ALREADY_EXISTS )
{
_ASSERTE( 0 );
return FALSE;
}
}
CString strDirPath;
strDirPath.Format(_T("%s\\"), pszDirName);
UINT nByte = WideCharToMultiByte(CP_ACP,0, (LPCTSTR)strDirPath,-1,NULL,0,NULL,NULL);
char *pszDirPath = new char[nByte+1];
memset(pszDirPath,0,nByte+1);
WideCharToMultiByte(CP_ACP, 0, strDirPath, -1, pszDirPath, nByte, NULL, NULL);
DWORD dwNum = 0;
if( IMG_ExtractMovie(pMovie, pszDirPath, &dwNum) != IMG_SUCCESS )
{
_ASSERTE( 0 );
return FALSE;
}
return TRUE;
}
// 此函数定义在bmp_decode.c中
//extern "C" uint32 IMG_ExtractMovieByIdx(
// const uint8* code_stream,
// uint8 ** pBmp,
// uint16 index
// );
BOOL CBmpProcessor::UnCompressMovie( LPBYTE pMovie, int nIdx, LPBYTE &pBmp )
{
if( IMG_ExtractMovieByIdx(pMovie, &pBmp, nIdx) != IMG_SUCCESS )
{
_ASSERTE( 0 );
IMG_xFreeMem(pBmp);
_tcscpy(m_szErrMsg, _T("UnCompressMovie fail!") );
return FALSE;
}
return TRUE;
}
BOOL CBmpProcessor::BmpConvertToBigEndian(LPBYTE p565Bmp, int nSize, BOOL bCompressed)
{
UNUSED_ALWAYS(bCompressed);
int nImgSize = 0;//数据区大小,以字节为单位
int nOffset = 0;
CConverter convert;
BITMAPFILEHEADER *pBmfh = (BITMAPFILEHEADER *)p565Bmp;
nOffset = pBmfh->bfOffBits;
pBmfh->bfType = convert.LitEdnToBigEdn(pBmfh->bfType);
pBmfh->bfSize = convert.ConvEdn_INT(pBmfh->bfSize);
pBmfh->bfReserved1= convert.LitEdnToBigEdn(pBmfh->bfReserved1);
pBmfh->bfReserved2 = convert.LitEdnToBigEdn(pBmfh->bfReserved2);
pBmfh->bfOffBits = convert.ConvEdn_INT(pBmfh->bfOffBits);
BITMAPINFOHEADER *pBmih = (BITMAPINFOHEADER *)(pBmfh+1);
nImgSize = pBmih->biSizeImage;
pBmih->biSize = convert.ConvEdn_INT(pBmih->biSize);
pBmih->biWidth = convert.ConvEdn_INT(pBmih->biWidth);
pBmih->biHeight = convert.ConvEdn_INT(pBmih->biHeight);
pBmih->biPlanes = convert.LitEdnToBigEdn(pBmih->biPlanes);
pBmih->biBitCount = convert.LitEdnToBigEdn(pBmih->biBitCount);
pBmih->biCompression = convert.ConvEdn_INT(pBmih->biCompression);
pBmih->biSizeImage = convert.ConvEdn_INT(pBmih->biSizeImage);
pBmih->biXPelsPerMeter = convert.ConvEdn_INT(pBmih->biXPelsPerMeter);
pBmih->biYPelsPerMeter = convert.ConvEdn_INT(pBmih->biYPelsPerMeter);
pBmih->biClrUsed = convert.ConvEdn_INT(pBmih->biClrUsed);
pBmih->biClrImportant = convert.ConvEdn_INT(pBmih->biClrImportant);
if(nOffset == sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + 3*sizeof(DWORD))
{
//3个DWORD 颜色掩码
LPDWORD lpdwClr = (LPDWORD)(pBmih+1);
for(int i = 0; i < 3; i++)
{
*(lpdwClr+i) = convert.ConvEdn_INT(*(lpdwClr+i));
}
}
//数据区
LPWORD lpwData = (LPWORD)(p565Bmp+nOffset);
// if(!bCompressed)
convert.LitEdnToBigEdn(lpwData,nImgSize/2);
return TRUE;
}
BOOL CBmpProcessor::BmpConvertToLitEndian(LPBYTE p565Bmp, int nSize, BOOL bCompressed)
{
UNUSED_ALWAYS(bCompressed);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -