www.pudn.com > ImgFFT.zip > 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)&amt;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)&amt;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*)&amt;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)&amt;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&amt; 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&amt;&amt;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)&amt;*(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))&amt;(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&amt;&amt;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);

}