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

📄 dibdc.cpp

📁 实现JPEG编码功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:

// DIBDC.cpp: implementation of the CDIBDC class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DIBDC.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define HIMETRIC_INCH	2540
#define PIXEL_PER_METER	3780
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CDIBDC, CDC)

VOID CDIBDC::ResetParams()
{
	m_hDIBitmap = NULL;
	m_Index=NULL;
	m_pData=NULL;	
}

CDIBDC::CDIBDC()
{
	ResetParams();

	m_BitmapInfo.bmiHeader.biSize=sizeof(m_BitmapInfo.bmiHeader);
	m_BitmapInfo.bmiHeader.biPlanes=1;
	m_BitmapInfo.bmiHeader.biCompression=BI_RGB;
	m_BitmapInfo.bmiHeader.biSizeImage=0;
	m_BitmapInfo.bmiHeader.biXPelsPerMeter=PIXEL_PER_METER;
	m_BitmapInfo.bmiHeader.biYPelsPerMeter=PIXEL_PER_METER;
	m_BitmapInfo.bmiHeader.biClrUsed=0;
	m_BitmapInfo.bmiHeader.biClrImportant=0;

	CreateDIB(10, 10, 8);
}

CDIBDC::~CDIBDC()
{
	DestroyDIB();
}

BOOL CDIBDC::CreateDIB(LONG width, LONG height, WORD bits)
{ 
	m_BitmapInfo.bmiHeader.biHeight=height;
	m_BitmapInfo.bmiHeader.biWidth=width;
	m_BitmapInfo.bmiHeader.biBitCount=bits;

	if(!ResetDIB())
		return FALSE;

	if(bits<=8)
	{
		SetDefaultColors();
	}
	return TRUE;
}

BOOL CDIBDC::ResetDIB()
{
	if(m_hDC == NULL)
	{
		if(!CreateCompatibleDC(NULL))
			return FALSE;
	}

	m_hDIBitmap=::CreateDIBSection(m_hDC,&m_BitmapInfo,DIB_RGB_COLORS,(void**)&m_pData,NULL,0);
	if(m_hDIBitmap == NULL)
		return FALSE;

	if(m_pData != NULL)
	{
		if(LockIndex() == NULL)
		{
			::DeleteObject(m_hDIBitmap);
			m_hDIBitmap = NULL;
			m_pData = NULL;
			m_Index = NULL;
			return FALSE;
		}
	}

	::DeleteObject(::SelectObject(m_hDC,m_hDIBitmap));

	return TRUE;
}

void CDIBDC::SetColors(int index, BYTE r, BYTE g, BYTE b)
{
	if(index>255)
		return;
	RGBQUAD color;
	::GetDIBColorTable(m_hDC, index, 1, &color);
	color.rgbRed=r;
	color.rgbGreen=g;
	color.rgbBlue=b;
	::SetDIBColorTable(m_hDC,index,1,&color);
}

INT CDIBDC::GetFreeImage(CFile *pFile)
{
	WORD width,height;
	pFile->SeekToBegin();
	pFile->Read(&width,2);
	pFile->Read(&height,2);
	if(DWORD(width)*height+4!=pFile->GetLength())
		return FALSE;
	CreateDIB(width,height,8);
	SetDefaultColors(TRUE);
	for(WORD i=0;i<height;i++)
	{
		pFile->Read(&(m_pData[(height-i-1)*RowBytes()]),width);
	}
	return TRUE;
}

void CDIBDC::SaveFreeImage(CFile *pFile, BOOL IsGray)
{
	if(Bits()!=8 || IsGray==FALSE)
	{
		CDIBDC tempDC;
		tempDC.CreateDIB(Width(),abs(Height()),8);
		tempDC.SetDefaultColors(TRUE);
		this->Paste(&tempDC,0,0);
		*this=tempDC;
	}

	pFile->SeekToBegin();
	WORD width=WORD(Width());
	WORD height=WORD(Height());
	pFile->Write(&width,2);
	pFile->Write(&height,2);
	for(WORD i=0;i<height;i++)
	{
		pFile->Write(&(m_pData[(height-i-1)*RowBytes()]),width);
	}
}

BOOL CDIBDC::GetBitmap(CFile * pFile)
{
	char bm[3];
	DWORD value;
	DWORD lHeadLength;
	DWORD TotalSize;
	pFile->SeekToBegin();
	pFile->Read(bm,2);
	if(bm[0]!='B' || bm[1]!='M')
		return FALSE;
	pFile->Read(&TotalSize,4);
	if(pFile->GetLength()<TotalSize)
		return FALSE;
	pFile->Read(&value,4);
	pFile->Read(&lHeadLength,4);
	INT bihSize;
	pFile->Read(&bihSize,4);
	ULONGLONG current=pFile->Seek(-4l,CFile::current);
	if(m_BitmapInfo.bmiHeader.biSize+current>pFile->GetLength())
		return FALSE;
	if(bihSize == sizeof(BITMAPINFOHEADER))
		pFile->Read(&m_BitmapInfo.bmiHeader,m_BitmapInfo.bmiHeader.biSize);
	else
		return FALSE;

	ResetDIB();

	LONG ColorsSize=lHeadLength-m_BitmapInfo.bmiHeader.biSize-0xE;
	if(ColorsSize>0)
	{
		RGBQUAD colors[256];
		pFile->Read(colors,ColorsSize);
		SetColorTable(colors);
	}
	pFile->Read(m_pData,ImageSize());
	return TRUE;
}

void CDIBDC::SaveBitmap(CFile * pFile)
{
	char bm[3]="BM";
	LONG value=0;
	LONG lHeadLength=0xE+m_BitmapInfo.bmiHeader.biSize;
	if(Bits()<=8)
		lHeadLength+=4*(1<<Bits());
	LONG TotalSize=ImageSize()+lHeadLength;
	BITMAPINFOHEADER bmiHeader=m_BitmapInfo.bmiHeader;
	if(Height()<0)
		bmiHeader.biHeight=-Height();
	pFile->SeekToBegin();
	pFile->Write(bm,2);
	pFile->Write(&TotalSize,4);
	pFile->Write(&value,4);
	pFile->Write(&lHeadLength,4);
	pFile->Write(&bmiHeader,bmiHeader.biSize);
	if(Bits()<=8)
	{
		RGBQUAD ColorTable[256];
		GetColorTable(ColorTable);
		pFile->Write(ColorTable,4*(1<<Bits()));
	}
	if(Height()>0)
	{
		pFile->Write(m_pData,ImageSize());
	}
	else
	{
		for(int i=-Height()-1;i>=0;i--)
		{
			pFile->Write(m_Index[i], RowBytes());
		}
	}
}

void CDIBDC::SetDefaultColors(BOOL IsGray)
{
	if(!IsValid())
		return;

	RGBQUAD	ColorTable[256];

	switch(Bits())
	{
	case 1:
		ColorTable[0].rgbRed=0;
		ColorTable[0].rgbGreen=0;
		ColorTable[0].rgbBlue=0;
		ColorTable[0].rgbReserved=0;
		ColorTable[1].rgbRed=0xff;
		ColorTable[1].rgbGreen=0xff;
		ColorTable[1].rgbBlue=0xff;
		ColorTable[1].rgbReserved=0;
		SetColorTable(ColorTable);
		break;
	case 4:
		if(IsGray)
		{
			for(int i=0;i<16;i++)
			{
				ColorTable[i].rgbRed=i<<4;
				ColorTable[i].rgbGreen=i<<4;
				ColorTable[i].rgbBlue=i<<4;
				ColorTable[i].rgbReserved=0;
			}
		}
		else
		{
			for(int i=0;i<16;i++)
			{
				int r,g,b,l;
				if(i&8)l=0x7f;
				else l=0;
				if(i&1)r=0x80;
				else r=0;
				if(i&2)g=0x80;
				else g=0;
				if(i&4)b=0x80;
				else b=0;

				ColorTable[i].rgbRed=r+l;
				ColorTable[i].rgbGreen=g+l;
				ColorTable[i].rgbBlue=b+l;
				ColorTable[i].rgbReserved=0;
			}
		}
		SetColorTable(ColorTable);
		break;
	case 8:
		if(IsGray)
		{
			for(int i=0;i<256;i++)
			{
				ColorTable[i].rgbRed=i;
				ColorTable[i].rgbGreen=i;
				ColorTable[i].rgbBlue=i;
				ColorTable[i].rgbReserved=0;
			}
		}
		else
		{
			BYTE r=0,g=0,b=0xc0;
			for(int i=0;i<256;i++)
			{
				b+=0x40;
				if(b>0x80)b=0xff;
				if(b==0x3f)
				{	
					b=0;
					g+=0x20;
					if(g>0xc0)g=0xff;
					if(g==0x1f)
					{
						g=0;
						r+=0x20;
						if(r>0xc0)r=0xff;
					}
				}
				ColorTable[i].rgbRed=r;
				ColorTable[i].rgbGreen=g;
				ColorTable[i].rgbBlue=b;
				ColorTable[i].rgbReserved=0;
			}
		}
		SetColorTable(ColorTable);
		break;
	default:break;
	}
}

void CDIBDC::Paste(CDC* pDC,
					 int XDest, int YDest, 
					 int nDestWidth, int nDestHeight, 
					 int XSrc, int YSrc, 
					 int nSrcWidth, int nSrcHeight, 
					 DWORD dwRop)
{
	ASSERT(pDC != NULL && IsValid());
	
	pDC->StretchBlt(
		XDest,YDest,nDestWidth,nDestHeight,
		this,
		XSrc,YSrc,nSrcWidth,nSrcHeight,
		dwRop);
}

void CDIBDC::Paste(CDC* pDC,
					 int XDest, int YDest, 
					 int nWidth, int nHeight, 
					 int XSrc, int YSrc, 
					 DWORD dwRop)
{
	ASSERT(pDC != NULL && IsValid());
	
	pDC->StretchBlt(
		XDest,YDest,nWidth,nHeight,
		this,
		XSrc,YSrc,nWidth,nHeight,
		dwRop);
}

void CDIBDC::Paste(CDC* pDC,
					 int XDest, int YDest, 
					 int nDestWidth, int nDestHeight, 
					 DWORD dwRop)
{
	ASSERT(pDC != NULL && IsValid());

	pDC->StretchBlt(
		XDest,YDest,nDestWidth,nDestHeight,
		this,
		0,0,Width(),abs(Height()),
		dwRop);
}

void CDIBDC::Paste(CDC* pDC,
					 int XDest, int YDest, 
					 DWORD dwRop)
{
	ASSERT(pDC != NULL && IsValid());
	
	pDC->StretchBlt(
		XDest,YDest,Width(),abs(Height()),
		this,
		0,0,Width(),abs(Height()),
		dwRop);
}

BOOL CDIBDC::CreateCompatibleDC(CDC * pDC)
{
	DeleteDC();
	CDC::CreateCompatibleDC(pDC);

	if(m_hDIBitmap != NULL)
	{
		if(m_hDC != NULL)
			::SelectObject(m_hDC,m_hDIBitmap);
		else
			DestroyDIB();
	}

	return m_hDC != NULL;
}

BOOL CDIBDC::ClipboardCopy()
{
	BOOL bHaveCopied=FALSE;
	if(OpenClipboard(AfxGetMainWnd()->m_hWnd))
	{
		if(EmptyClipboard())
		{
			HGLOBAL hDIB=GlobalAlloc(GMEM_MOVEABLE,DIBSize());
			PVOID pDIB=GlobalLock(hDIB);
			SaveToMem(pDIB);
			SetClipboardData(CF_DIB,hDIB);
			GlobalUnlock(hDIB);
			bHaveCopied=TRUE;
		}
		CloseClipboard();
	}
	return bHaveCopied;
}

BOOL CDIBDC::ClipboardPaste()
{
	BOOL bHavePasted=FALSE;
	if(OpenClipboard(AfxGetMainWnd()->m_hWnd))
	{
		if(IsClipboardFormatAvailable(CF_DIB))
		{
			HGLOBAL hDIB=GetClipboardData(CF_DIB);
			PVOID pDIB=GlobalLock(hDIB);
			bHavePasted = LoadFromMem(pDIB);
			GlobalUnlock(hDIB);
		}
		CloseClipboard();
	}
	return bHavePasted;
}

BOOL CDIBDC::ClipboardAvailable()
{
	BOOL bIsAvailable=FALSE;
	if(OpenClipboard(AfxGetMainWnd()->m_hWnd))
	{
		if(IsClipboardFormatAvailable(CF_DIB))
		{
			bIsAvailable=TRUE;
		}
		CloseClipboard();
	}
	return bIsAvailable;

}

LONG& CDIBDC::Width()
{
	return m_BitmapInfo.bmiHeader.biWidth;
}

LONG& CDIBDC::Height()
{
	return m_BitmapInfo.bmiHeader.biHeight;
}

DWORD CDIBDC::ImageSize()
{
	return abs(Height())*RowBytes();
}

WORD& CDIBDC::Bits()
{
	return m_BitmapInfo.bmiHeader.biBitCount;
}

LONG CDIBDC::RowBytes()
{
	return ((Width()*Bits() + 7)/8+3)/4*4;
}

void CDIBDC::SetColorTable(RGBQUAD * pColors)
{
	if(Bits()<=8)
	::SetDIBColorTable(m_hDC,0,1<<Bits(),pColors);
}

BOOL CDIBDC::GetColorTable(RGBQUAD *pColors)
{
	if(IsValid() && Bits() <= 8)
	{
		::GetDIBColorTable(m_hDC, 0, 1<<Bits(), pColors);
		return TRUE;
	}
	else
		return FALSE;
}

BOOL CDIBDC::ResizeDIB(LONG width, LONG height)
{
	if(Width()==width && Height()==height)
		return TRUE;

	LONG tempWidth=Width();
	LONG tempHeight=Height();

	Height()=height;
	Width()=width;
	m_BitmapInfo.bmiHeader.biSizeImage=0;

	RGBQUAD ColorTable[256];
	GetColorTable(ColorTable);
	HBITMAP hDIBitmap=::CreateDIBSection(m_hDC,&m_BitmapInfo,DIB_RGB_COLORS,(PVOID*)&m_pData,NULL,0);
	HBITMAP hTempDIB=HBITMAP(::SelectObject(m_hDC,hDIBitmap));
	SetColorTable(ColorTable);

	LONG minWidth=Width();
	if(minWidth>tempWidth)
		minWidth=tempWidth;
	LONG minHeight=abs(Height());
	if(minHeight>abs(tempHeight))
		minHeight=abs(tempHeight);

	CDC tempDC;
	tempDC.CreateCompatibleDC(this);
	tempDC.SelectObject(hTempDIB);
	this->BitBlt(0,0,minWidth,minHeight,&tempDC,0,0,SRCCOPY);
	tempDC.DeleteDC();
	::DeleteObject(hTempDIB);

	LockIndex();

	return TRUE;
}

BOOL CDIBDC::AddDIB(CDIBDC & DIBDC, int x, int y, BOOL IsSuitable)
{
	if(x<0 || y<0)
		return FALSE;
	if(IsSuitable)
	{
		LONG width=x+DIBDC.Width();
		if(Width()>width)
			width=Width();
		LONG height=y+abs(DIBDC.Height());
		if(abs(Height())>height)
			height=abs(Height());
		ResizeDIB(width,height);
	}
	BitBlt(x,y,DIBDC.Width(),DIBDC.Height(),&DIBDC,0,0,SRCCOPY);
	return TRUE;
}

BOOL CDIBDC::CreateDIB(CDIBDC & DIBDC, int x, int y, int width, int height)
{
	if(DIBDC.m_pData == NULL)
		return FALSE;

	memcpy(&m_BitmapInfo,&DIBDC.m_BitmapInfo,40);
	Height()=height;
	Width()=width;
	if(!ResetDIB())
		return FALSE;

	RGBQUAD ColorTable[256];
	DIBDC.GetColorTable(ColorTable);
	SetColorTable(ColorTable);

	BitBlt(0,0,width,height,&DIBDC,x,y,SRCCOPY);

	return TRUE;
}

BOOL CDIBDC::CreateDIB(CDIBDC & DIBDC)
{
	if(DIBDC.m_pData == NULL)
		return FALSE;

	if(&DIBDC == this)
		return TRUE;

	memcpy(&m_BitmapInfo,&DIBDC.m_BitmapInfo,40);
	if(!ResetDIB())
		return FALSE;
	memcpy(m_pData,DIBDC.m_pData,ImageSize());
	if(Bits()<=8)
	{
		RGBQUAD ColorTable[256];
		DIBDC.GetColorTable(ColorTable);
		SetColorTable(ColorTable);
	}
	return TRUE;
}

CDIBDC::CDIBDC(CDIBDC & DIBDC)
{
	m_hDIBitmap = NULL;
	m_Index=NULL;
	m_pData=NULL;
	CDC::CreateCompatibleDC(&DIBDC);
	CreateDIB(DIBDC);
}

CDIBDC& CDIBDC::operator=(CDIBDC& DIBDC)
{
	if(&DIBDC == this)
		return (*this);
	
	DestroyDIB();
	CreateCompatibleDC(&DIBDC);
	CreateDIB(DIBDC);
	return (*this);
}

BOOL CDIBDC::GetFromFile(CFile *pFile)
{
	CString suffix=pFile->GetFileName();
	int PointAt=suffix.Find('.');
	do
	{
		suffix=suffix.Mid(PointAt+1);
	}
	while((PointAt=suffix.Find('.'))!=-1);
	suffix.MakeLower();
	if(suffix=="bmp")
	{
		return GetBitmap(pFile);
	}
	if(suffix=="fri")
	{
		return GetFreeImage(pFile);
	}
	if(suffix=="bmc")
	{
		return GetCrypticBmp(pFile);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -