19,468
社区成员
发帖
与我相关
我的任务
分享
// Compression = BI_RGB,555 format。
// BI_BITFIELDS,RedMask、GreenMask、BlueMask 565 format
void CShow256BmpDlg::OnButton5()
{
// TODO: Add your control notification handler code here
CWaitCursor wait;
CFile file;
#if 0 // 555
file.Open("16.bmp",CFile::modeRead);
#else // 565
file.Open("16bf.bmp",CFile::modeRead);
#endif
int ImageSize=file.GetLength();// 436534;436480*2=872960
BYTE heads[sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER)];
int Herd=file.Read(heads,sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER));// 54
BITMAPFILEHEADER *pBmpFileHead=(BITMAPFILEHEADER *)heads;
BITMAPINFOHEADER *pBmpInfoHead=(BITMAPINFOHEADER *)(heads+sizeof (BITMAPFILEHEADER));
ImageSize = pBmpInfoHead->biSizeImage;// 436480 biSizeImage 872960 = 0xD5200
// bfOffBits 66-54=12/4=3DWORD
BOOL bl565=FALSE;
WORD ColorMask[3]={0};
if(pBmpInfoHead->biCompression == BI_BITFIELDS)
{
bl565=TRUE;
//
DWORD mk;
file.Read(&mk,sizeof(DWORD));
ColorMask[0]=(WORD)mk;
file.Read(&mk,sizeof(DWORD));
ColorMask[1]=(WORD)mk;
file.Read(&mk,sizeof(DWORD));
ColorMask[2]=(WORD)mk;
}
//
BYTE *bufferIn=new BYTE[ImageSize];
int len=file.Read(bufferIn,ImageSize);// len=436480
file.Close();
//
int height=pBmpInfoHead->biHeight;// 341
BYTE *bufferOut=new BYTE[ImageSize*2];
BYTE *pBufferIn=bufferIn;
BYTE *pBufferOut=bufferOut;
//
for (; height>0; height--)// 341
{
int width =pBmpInfoHead->biWidth;// 640
// vertical flip: pBufferOut=&bufferOut[(height-1)*width*4];
for (; width>0; width--)
{
//char prompt[40];
//sprintf(prompt,"0x%0X%0X", *(pBufferIn+1) ,*pBufferIn);
//afxDump << prompt << "\n";// 0x7BDE ; 0111 10-11 110-1 1111
BYTE red = 0;// 7 C
BYTE green = 0;// 3 E
BYTE blue = 0;// 1 F
if(bl565)
{// for 16bf.bmp ;3 masks are :7C00 , 03E0, 001F ;
red =((*(WORD *)pBufferIn) & ColorMask[0]) >> 7;//=0x7C00; 5(1st bit unused)
green =((*(WORD *)pBufferIn) & ColorMask[1]) >> 2;//=0x03E0; 5
blue =((*(WORD *)pBufferIn) & ColorMask[2]) << 3;//=0x001F; 5
// if(ColorMask[0]==0xF800
// BYTE red =((*(WORD *)pBuffer) & 0xF800) >> 8;// 5
// BYTE green =((*(WORD *)pBuffer) & 0x07E0) >> 3;// 6
// BYTE blue =((*(WORD *)pBuffer) & 0x001F) << 3;// 5
}
else
{
red =((*(WORD *)pBufferIn) & 0x7C00) >> 7;
green =((*(WORD *)pBufferIn) & 0x03E0) >> 2;
blue =((*(WORD *)pBufferIn) & 0x001F) << 3;
}
*pBufferOut=blue|7;// +7 ?
pBufferOut++;
*pBufferOut=green|7;
pBufferOut++;
*pBufferOut=red|7;
pBufferOut++;
*pBufferOut=0;
pBufferOut++;
pBufferIn += 2;
}
}
#if 0
CFile fileDat;
fileDat.Open("16bf.dat",CFile::modeCreate | CFile::modeWrite);
fileDat.Write(bufferOut,ImageSize*2);
fileDat.Close();
#endif
//
delete []bufferIn;
// draw
CClientDC dc(this); // device context for painting
CDC memDC;
memDC.CreateCompatibleDC(&dc);
// change bmp info
pBmpInfoHead->biSizeImage=ImageSize*2;
pBmpInfoHead->biBitCount=32;
pBmpInfoHead->biCompression=BI_RGB;
//
void* tempArray=NULL;
HBITMAP hBitmap=::CreateDIBSection(dc.m_hDC, (BITMAPINFO*)pBmpInfoHead,DIB_RGB_COLORS,&tempArray,NULL,0);
memcpy(tempArray,bufferOut,ImageSize*2);
delete []bufferOut;
//
memDC.SelectObject(hBitmap);
dc.BitBlt(0,0,pBmpInfoHead->biWidth,pBmpInfoHead->biHeight,&memDC,0,0,SRCCOPY);
}