|
/*
代码来源:
《Visual C++ 图形编程技巧与实例》
谭明金,人民邮电出版社
*/
//自定义位图类型
typedef struct _MYBITMAP {
COLORREF clrRGBA;
}MYBITMAP;
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
BOOL CImage::LoadImage(CFile& file) { //读取位图文件头
file.Read (&bmfHead,sizeof(BITMAPFILEHEADER));
if(bmfHead.bfType!=DIB_HEADER_MARKER)
{
MessageBox("File is not BMP!",NULL,MB_OK);
exit(1);
}
//读取位图信息头
file.Seek(14,CFile::begin);
file.Read (&bmHead,sizeof(BITMAPINFOHEADER));
if(bmHead.biCompression)
{
MessageBox("cannot open this compressed file!",NULL,MB_OK);
return;
}
//从堆中分配逐像素缓冲所需要容量的内存
tmp=bmHead.biWidth*bmHead.biBitCount;
nScan=tmp%32?(tmp/32*4+(tmp%32+32)/32*4):tmp/8;
rdBytes=nScan*bmHead.biHeight;
svBytes=bmHead.biWidth*bmHead.biHeight;
pTemp=new BYTE[rdBytes];
if(pBuff) delete pBuff;
pBuff=new MYBITMAP[svBytes];
if(!pBuff||!pTemp)
{
MessageBox("Cannot allocate memory","Memory allocate",MB_OK);
exit(0);
}
//读取位图数据
lOffset=bmfHead.bfOffBits;
file.Seek (lOffset,CFile::begin);
file.Read (pTemp,rdBytes);
//读取调色板
if(bmHead.biBitCount<24)
{
nEntries=Pow2(bmHead.biBitCount);
pRGBQUARD=new BYTE[nEntries*4];
file.Seek (54l,CFile::begin);
file.Read (pRGBQUARD,nEntries*4);
}
//进行数据转换
switch(bmHead.biBitCount)
{
case 1:nPixel=0;
for(i=bmHead.biHeight-1;i>=0;i--)
for(index=i*nScan,j=0;j<bmHead.biWidth;j++)
{
OneByte=pTemp[index+j/8];
iRGB=(OneByte&Pow2(7-j%8))?1:0;
pBuff[nPixel++].clrRGBA =RGB(pRGBQUARD[iRGB*4+2],
pRGBQUARD[iRGB*4+1],pRGBQUARD[iRGB*4]);
}
break;
case 4:nPixel=0;
for(i=bmHead.biHeight-1;i>=0;i--)
for(index=i*nScan,j=0;j<bmHead.biWidth;j++)
{ OneByte=pTemp[index+j*4/8];
iRGB=j%2?OneByte&0x0f:OneByte>>4;
pBuff[nPixel++].clrRGBA =RGB(pRGBQUARD[iRGB*4+2],
pRGBQUARD[iRGB*4+1],pRGBQUARD[iRGB*4]);
}
break;
case 8:nPixel=0;
for(i=bmHead.biHeight-1;i>=0;i--)
for(index=i*nScan,j=0;j<bmHead.biWidth;j++)
{ OneByte=pTemp[index+j];
iRGB=OneByte;
pBuff[nPixel++].clrRGBA =RGB(pRGBQUARD[iRGB*4+2],
pRGBQUARD[iRGB*4+1],pRGBQUARD[iRGB*4]);
}
break;
case 24:nPixel=0;
for(i=bmHead.biHeight-1;i>=0;i--)
for(index=i*nScan,j=0;j<bmHead.biWidth;j++)
{ pBuff[nPixel++].clrRGBA =RGB(pTemp[index+2],
pTemp[index+1],pTemp[index]);
index+=3;
}
break;
default:
MessageBox("File not supported.",NULL,MB_OK);
exit(1);
}
//释放临时资源
if(pTemp) delete pTemp;
if(pRGBQUARD) delete pRGBQUARD;
} |