📄 cdib.cpp
字号:
//CDib.cpp:implement the operations of proccessing DIB
#include "stdafx.h"
#include "Pro2.h"
#include "Pro2Doc.h"
#include "Pro2View.h"
#include "CDib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CDib,CObject,0)
/////////////////////////////////////////////////////////////////////////
CDib::CDib()
{
m_hFile=NULL;
m_hBitmap=NULL;
m_hPalette=NULL;
m_nBmihAlloc=m_nImageAlloc=noAlloc;
Empty();
}
CDib::CDib(CSize size,int nBitCount)
{
m_hFile=NULL;
m_hBitmap=NULL;
m_hPalette=NULL;
m_nBmihAlloc=m_nImageAlloc=noAlloc;
Empty();
ComputePaletteSize(nBitCount);
m_lpBMIH=(LPBITMAPINFOHEADER)new
char[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries];
m_nBmihAlloc=crtAlloc;
m_lpBMIH->biSize=sizeof(BITMAPINFOHEADER);
m_lpBMIH->biWidth=size.cx;
m_lpBMIH->biHeight=size.cy;
m_lpBMIH->biPlanes=1;
m_lpBMIH->biBitCount=nBitCount;
m_lpBMIH->biCompression=BI_RGB;
m_lpBMIH->biSizeImage=0;
m_lpBMIH->biXPelsPerMeter=0;
m_lpBMIH->biYPelsPerMeter=0;
m_lpBMIH->biClrUsed=m_nColorTableEntries;
m_lpBMIH->biClrImportant=m_nColorTableEntries;
ComputeMetrics();
memset(m_lpvColorTable,0,sizeof(RGBQUAD)*m_nColorTableEntries);
m_lpImage=NULL;
}
CDib::~CDib()
{
Empty();
}
////////////////////////////////////////////////////////////////////////////
//put data of a file in or out
BOOL CDib::Read(CFile *pFile)
{
Empty();
int nCount,nSize;
BITMAPFILEHEADER bmfh;
char ko[100];
try
{
nCount=pFile->Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));
if(nCount!=sizeof(BITMAPFILEHEADER))
{
throw new CException;
}
if(bmfh.bfType!=0x4d42)
{
throw new CException;
}
nSize=bmfh.bfOffBits-sizeof(BITMAPFILEHEADER);
m_lpBMIH=(LPBITMAPINFOHEADER)new char[nSize];
m_nBmihAlloc=m_nImageAlloc=crtAlloc;
nCount=pFile->Read(m_lpBMIH,nSize);
ComputeMetrics();
ComputePaletteSize(m_lpBMIH->biBitCount);
MakePalette();
m_lpImage=(LPBYTE)new char[m_dwSizeImage];
nCount=pFile->Read(m_lpImage,m_dwSizeImage);
for(int i=0;i<100;i++)
{
ko[i]=*(m_lpImage+i+220000);
}
}
catch(CException *pe)
{
AfxMessageBox("Read Error!");
pe->Delete();
return FALSE;
}
return TRUE;
}
BOOL CDib::ReadSection(CFile *pFile,CDC* pDC)//=NULL
{
Empty();
int nCount,nSize;
BITMAPFILEHEADER bmfh;
try
{
nCount=pFile->Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));
if(nCount!=sizeof(BITMAPFILEHEADER))
{
throw new CException;
}
if(bmfh.bfType!=0x4d42)
{
throw new CException;
}
nSize=bmfh.bfOffBits-sizeof(BITMAPINFOHEADER);
m_lpBMIH=(LPBITMAPINFOHEADER)new char[nSize];
m_nBmihAlloc=crtAlloc;
m_nImageAlloc=noAlloc;
nCount=pFile->Read(m_lpBMIH,nSize);
if(m_lpBMIH->biCompression!=BI_RGB)
{
throw new CException;
}
ComputeMetrics();
ComputePaletteSize(m_lpBMIH->biBitCount);
MakePalette();
//here is the differences from Read().
UsePalette(pDC);
//here is the differences from Read().
m_hBitmap=::CreateDIBSection(pDC->GetSafeHdc(),(LPBITMAPINFO)m_lpBMIH,
DIB_RGB_COLORS,(LPVOID*)&m_lpImage,NULL,0);
ASSERT(m_lpImage!=NULL);
nCount=pFile->Read(m_lpImage,m_dwSizeImage);
}
catch(CException *pe)
{
AfxMessageBox("ReadSection Error!");
pe->Delete();
return FALSE;
}
return FALSE;
}
BOOL CDib::Write(CFile* pFile)
{
BITMAPFILEHEADER bmfh;
bmfh.bfType=0x4d42;
int nSizeHdr=sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;
bmfh.bfSize=sizeof(BITMAPFILEHEADER)+nSizeHdr+m_dwSizeImage;
bmfh.bfReserved1=bmfh.bfReserved2=0;
bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;
try
{
pFile->Write((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));
pFile->Write((LPVOID)m_lpBMIH,nSizeHdr);
pFile->Write((LPVOID)m_lpImage,m_dwSizeImage);
}
catch(CException *pe)
{
AfxMessageBox("Write Error!");
pe->Delete();
return FALSE;
}
return TRUE;
}
void CDib::Serialize(CArchive& ar)
{
DWORD dwPos;
dwPos=ar.GetFile()->GetPosition();
TRACE("CDib::Serialize--pos=%d\n",dwPos);
ar.Flush();
dwPos=ar.GetFile()->GetPosition();
TRACE("CDib::Serialize--pos=%d\n",dwPos);
if(ar.IsStoring())
{
Write(ar.GetFile());
}
else
{
Read(ar.GetFile());
}
}
//////////////////////////////////////////////////////////////////////////
//show up a picture in DIB form.
BOOL CDib::Draw(CDC* pDC,CPoint origin,CSize size)
{
if(m_lpBMIH==NULL) return FALSE;
if(m_hPalette!=NULL)
{
::SelectPalette(pDC->GetSafeHdc(),m_hPalette,TRUE);
}
pDC->SetStretchBltMode(COLORONCOLOR);
::StretchDIBits(pDC->GetSafeHdc(),origin.x,origin.y,size.cx,size.cy,
0,0,m_lpBMIH->biWidth,m_lpBMIH->biHeight,m_lpImage,
(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS,SRCCOPY);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
//operate a palette
BOOL CDib::MakePalette()
{
if(m_nColorTableEntries==0) return FALSE;
if(m_hPalette!=NULL) ::DeleteObject(m_hPalette);
TRACE("CDib::MakePalette--m_nColorTableEntries=%d\n",m_nColorTableEntries);
LPLOGPALETTE pLogPal=(LPLOGPALETTE)new char[sizeof(DWORD)+m_nColorTableEntries*sizeof(PALETTEENTRY)];
pLogPal->palVersion=0x300;
pLogPal->palNumEntries=m_nColorTableEntries;
LPRGBQUAD pDibQuad=(LPRGBQUAD)m_lpvColorTable;
for(int i=0;i<m_nColorTableEntries;i++)
{
pLogPal->palPalEntry[i].peRed=pDibQuad->rgbRed;
pLogPal->palPalEntry[i].peGreen=pDibQuad->rgbGreen;
pLogPal->palPalEntry[i].peBlue=pDibQuad->rgbBlue;
pLogPal->palPalEntry[i].peFlags=0;
}
m_hPalette=::CreatePalette(pLogPal);
delete[] pLogPal;
return TRUE;
}
BOOL CDib::SetSystemPalette(CDC* pDC)
{
if(m_nColorTableEntries==0) return FALSE;
m_hPalette=::CreateHalftonePalette(pDC->GetSafeHdc());
return TRUE;
}
UINT CDib::UsePalette(CDC* pDC,BOOL bBackGround)
{
if(m_hPalette==NULL) return 0;
HDC hdc=pDC->GetSafeHdc();
::SelectPalette(hdc,m_hPalette,bBackGround);
return ::RealizePalette(hdc);
}
/////////////////////////////////////////////////////////////////////////////
//release located memory and check whether being empty
void CDib::Empty()
{
DetachMapFile();
if(m_nBmihAlloc==crtAlloc)
{
delete[] m_lpBMIH;
}
else
{
if(m_nBmihAlloc==heapAlloc)
{
::GlobalUnlock(m_hGlobal);
::GlobalFree(m_hGlobal);
}
}
if(m_nImageAlloc==crtAlloc) delete[] m_lpImage;
if(m_hPalette!=NULL) ::DeleteObject(m_hPalette);
if(m_hBitmap!=NULL) ::DeleteObject(m_hBitmap);
m_nBmihAlloc=m_nImageAlloc=noAlloc;
m_hGlobal=NULL;
m_lpBMIH=NULL;
m_lpImage=NULL;
m_lpvColorTable=NULL;
m_nColorTableEntries=0;
m_dwSizeImage=0;
m_lpvFile=NULL;
m_hMap=NULL;
m_hFile=NULL;
m_hBitmap=NULL;
m_hPalette=NULL;
}
BOOL CDib::IsEmpty()
{
if(m_lpBMIH==NULL&&m_lpImage==NULL)
return TRUE;
else
return FALSE;
}
////////////////////////////////////////////////////////////////////////////
//operate internal memory
void CDib::DetachMapFile()
{
if(m_hFile==NULL) return;
::UnmapViewOfFile(m_lpvFile);
::CloseHandle(m_hMap);
::CloseHandle(m_hFile);
m_hFile=NULL;
}
////////////////////////////////////////////////////////////////////////////
//compute numbers
void CDib::ComputeMetrics()
{
m_lpvColorTable=m_lpBMIH+sizeof(BITMAPFILEHEADER);
if(m_lpBMIH->biSizeImage==0)
{
DWORD dwBytes=(DWORD)m_lpBMIH->biWidth*m_lpBMIH->biBitCount/32;
if((DWORD)m_lpBMIH->biWidth*m_lpBMIH->biBitCount%32)
dwBytes++;
dwBytes*=4;
m_lpBMIH->biSizeImage=dwBytes*m_lpBMIH->biHeight;
}
m_dwSizeImage=m_lpBMIH->biSizeImage;
}
void CDib::ComputePaletteSize(int nBitCount)
{
if(nBitCount)
{
switch(nBitCount)
{
case 1:
m_nColorTableEntries=2;
break;
case 4:
m_nColorTableEntries=16;
break;
case 8:
m_nColorTableEntries=256;
break;
case 16:
case 24:
case 32:
m_nColorTableEntries=0;
break;
default:
break;
}
}
}
////////////////////////////////////////////////////////////////////////////
//get attributes of a DIB picture
CSize CDib::GetDibSaveDim()
{
CSize sizeSaveDim;
int k=(m_lpBMIH->biWidth*m_lpBMIH->biBitCount+31)/32*4;
sizeSaveDim.cx=(m_lpBMIH->biWidth*m_lpBMIH->biBitCount+31)/32*4;
sizeSaveDim.cy=m_lpBMIH->biHeight;
return sizeSaveDim;
}
CSize CDib::GetDimension()
{
if(m_lpBMIH==NULL) return CSize(0,0);
return CSize((int)m_lpBMIH->biWidth,m_lpBMIH->biHeight);
}
LONG CDib::GetPixelOffset(int x,int y)
{
CSize sizeSaveDim;
sizeSaveDim=GetDibSaveDim();
LONG lOffset=(LONG)(sizeSaveDim.cy-y-1)*sizeSaveDim.cx+x*m_lpBMIH->biBitCount/8;
return lOffset;
}
RGBQUAD CDib::GetPixel(int x,int y)
{
RGBQUAD cColor;
switch(m_lpBMIH->biBitCount)
{
case 1:
if(1<<(7-x%8)&*(LPBYTE)(m_lpImage+GetPixelOffset(x,y)))
{
cColor.rgbBlue=255;
cColor.rgbGreen=255;
cColor.rgbRed=255;
cColor.rgbReserved=0;
}
else
{
cColor.rgbBlue=0;
cColor.rgbGreen=0;
cColor.rgbRed=0;
cColor.rgbReserved=0;
}
break;
case 4:
{//{} is necessary here.
int nIndex=(*(LPBYTE)(m_lpImage+GetPixelOffset(x,y))&(x%2?0x0f:0xf0))
>>(x%2?0:4);
LPRGBQUAD pDibQuad=(LPRGBQUAD)(m_lpvColorTable)+nIndex;
cColor.rgbBlue=pDibQuad->rgbBlue;
cColor.rgbGreen=pDibQuad->rgbGreen;
cColor.rgbRed=pDibQuad->rgbRed;
cColor.rgbReserved=0;
}
break;
case 8:
{
int nIndex=*(BYTE*)(m_lpImage+GetPixelOffset(x,y));
LPRGBQUAD pDibQuad=(LPRGBQUAD)(m_lpvColorTable)+nIndex;
cColor.rgbBlue=pDibQuad->rgbBlue;
cColor.rgbGreen=pDibQuad->rgbGreen;
cColor.rgbRed=pDibQuad->rgbRed;
cColor.rgbReserved=0;
}
break;
default:
int nIndex=*(BYTE*)(m_lpImage+GetPixelOffset(x,y));
cColor.rgbBlue=m_lpImage[nIndex];
cColor.rgbGreen=m_lpImage[nIndex+1];
cColor.rgbRed=m_lpImage[nIndex+2];
cColor.rgbReserved=0;
break;
}
return cColor;
}
/*
int CDib::GetSizeImage(){return m_dwSizeImage;}
int CDib::GetSizeHeader()
{return sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;}
*/
WORD CDib::PaletteSize()
{
WORD NumColors;
LPBITMAPINFOHEADER lpbi=m_lpBMIH;
NumColors=(m_lpBMIH->biClrUsed==0&&m_lpBMIH->biBitCount<=8)?
(int)(1<<m_lpBMIH->biBitCount):(int)m_lpBMIH->biClrUsed;//int is equal to WORD
//in the structure, *?*:*, () is needed outside the second and the last *.
//the way of the definition of color is not the same with BITMAPINFOHEADER.
if(lpbi->biSize==sizeof(BITMAPCOREHEADER))
return NumColors*sizeof(RGBTRIPLE);
else
return NumColors*sizeof(RGBQUAD);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -