⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdib.cpp

📁 《数字图象工程案例》原码
💻 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 + -