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

📄 cdib.cpp

📁 基于DCT的小波变换EZW压缩算法以及毕业设计论文
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if(m_hPalette == NULL) return 0;

	// 得到设备上下文句柄
	HDC hdc = pDC->GetSafeHdc();

	// 选择调色板到设备上下文
	::SelectPalette(hdc, m_hPalette, bBackground);

	// 实现该调色板
	return ::RealizePalette(hdc);
}


/*************************************************************************
 *
 * \函数名称:
 *   Draw()
 *
 * \输入参数:
 *   CDC*	pDC			- 指向将要接收DIB图象的设备上下文指针
 *   CPoint	origin		- 显示DIB的逻辑坐标
 *   CSize	size		- 显示矩形的宽度和高度
 *
 * \返回值:
 *   BOOL				- 如果成功,则为TRUE,
 *
 * \说明:
 *   通过调用Win32 SDK的StretchDIBits函数将CDib对象输出到显示器(或者打印机)。
 *   为了适合指定的矩形,位图可以进行必要的拉伸
 *
 ************************************************************************
 */
BOOL CDib::Draw(CDC* pDC, CPoint origin, CSize size)
{
	// 如果信息头为空,表示尚未有数据,返回FALSE
	if(m_lpBMIH == NULL) return FALSE;

	// 如果调色板不为空,则将调色板选入设备上下文
	if(m_hPalette != NULL) 
	{
		::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
	}

	// 设置显示模式
	pDC->SetStretchBltMode(COLORONCOLOR);

	// 在设备的origin位置上画出大小为size的图象
	::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;
}


/*************************************************************************
 *
 * \函数名称:
 *   CreateSection()
 *
 * \输入参数:
 *   CDC*	pDC			- 设备上下文指针
 *
 * \返回值:
 *   HBITMAP				- 到GDI位图的句柄。如果不成功,则为NULL。
 *					- 该句柄也是作为公共数据成员存储的
 *
 * \说明:
 *   通过调用Win32 SDK的CreateDIBSection函数创建一个DIB段。图象内存将不被初始化
 *
 ************************************************************************
 */
HBITMAP CDib::CreateSection(CDC* pDC /* = NULL */)
{
	// 如果信息头为空,不作任何处理
	if(m_lpBMIH == NULL) return NULL;

	// 如果图象数据不存在,不作任何处理
	if(m_lpImage != NULL) return NULL; 

	// 创建一个DIB段
	m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,
		DIB_RGB_COLORS,	(LPVOID*) &m_lpImage, NULL, 0);	
	ASSERT(m_lpImage != NULL);

	// 返回HBIMAP句柄
	return m_hBitmap;
}


/*************************************************************************
 *
 * \函数名称:
 *   MakePalette()
 *
 * \输入参数:
 *   无
 *
 * \返回值:
 *   BOOL				- 如果成功,则为TRUE
 *
 * \说明:
 *   如果颜色表存在的话,该函数将读取它,并创建一个Windows调色板。
 *   HPALETTE存储在一个数据成员中。
 *
 ************************************************************************
 */
BOOL CDib::MakePalette()
{
	// 如果不存在调色板,则返回FALSE
	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[2 * sizeof(WORD) +
		m_nColorTableEntries * sizeof(PALETTEENTRY)];

	// 设置逻辑调色板的信息
	pLogPal->palVersion = 0x300;
	pLogPal->palNumEntries = m_nColorTableEntries;

	// 拷贝DIB中的颜色表到逻辑调色板
	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;
		pDibQuad++;
	}

	// 创建逻辑调色板
	m_hPalette = ::CreatePalette(pLogPal);

	// 删除临时变量并返回TRUE
	delete pLogPal;
	return TRUE;
}	


/*************************************************************************
 *
 * \函数名称:
 *   SetSystemPalette()
 *
 * \输入参数:
 *   CDC*	pDC			- 设备上下文指针
 *
 * \返回值:
 *   BOOL				- 如果成功,则为TRUE,
 *
 * \说明:
 *   如果16bpp、24bpp或32bppDIB不具备调色板,则该函数可以为CDib对象创建一个逻辑调色板,
 *   它与由CreatehalftonePalette函数返回的调色板相匹配。如果程序在256色调色板显示器上
 *   运行,而你又没有调用SetSystemPalette,那么,你将不具有任何调色板,只有20中标准的
 *   Windows颜色出现在DIB中
 *
 ************************************************************************
 */
BOOL CDib::SetSystemPalette(CDC* pDC)
{
	// 如果DIB不具备调色板,则需要利用系统的调色板
	if(m_nColorTableEntries != 0) return FALSE;
	
	// 为设备上下文创建中间调色板,并将其与CPalette对象连接
	m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc());

	// 返回
	return TRUE;
}


/*************************************************************************
 *
 * \函数名称:
 *   CreateBitmap()
 *
 * \输入参数:
 *   CDC*	pDC			- 设备上下文指针
 *
 * \返回值:
 *   HBITMAP				- 到GDI位图的句柄;如果不成功,则为NULL
 *					- 该句柄不是作为公共数据成员存储的
 *
 * \说明:
 *   从已有的DIB中创建DDB位图。不要将这个函数与CreateSection
 *   弄混了,后者的作用是生成DIB并保存句柄
 *
 ************************************************************************
 */
HBITMAP CDib::CreateBitmap(CDC* pDC)
{
	// 如果不存在图象数据,则返回NULL
	if (m_dwSizeImage == 0) return NULL;

	// 用指定的DIB来创建DDB,并用DIB信息初始化位图的图象位
	HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), m_lpBMIH,
		CBM_INIT, m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS);
	ASSERT(hBitmap != NULL);

	// 返回DDB位图句柄
	return hBitmap;
}


/*************************************************************************
 *
 * \函数名称:
 *   ConvertDDBToDIB()
 *
 * \输入参数:
 *   HBITMAP	hBitmap			- 指向源数据的BITMAP句柄
 *   CDib*	pDibDst			- 指向转换目标的CDib对象指针
 *
 * \返回值:
 *   BOOL				- 如果操作成功,则返回TRUE
 *
 * \说明:
 *   该函数将源BITMAP类pDibSrc中的数据拷贝到pDibDst中,并对相应的数据成员赋值
 *
 *************************************************************************
 */

BOOL CDib::ConvertFromDDB(HBITMAP hBitmap, HPALETTE hPal)
{
	// 声明一个BITMAP结构
	BITMAP bm;

	// 设备上下文
	HDC hDC;
	
	// 象素位数
	WORD biBitCount;
	
	// 调色板表项数
	int nColorTableEntries;

	// 如果hBitmap句柄无效,则返回
	if(!hBitmap){
		return FALSE;
	}

	
	// 释放已分配的内存
	Empty();
	
	// 填充图象数据到bm中,其中最后一个参数表示接收这个指定的对象的指针
	if(!GetObject(hBitmap,sizeof(BITMAP),(LPBYTE)&bm)){
		return FALSE;
	}

	// 计算象素位数
	biBitCount=bm.bmPlanes*bm.bmBitsPixel;
	if(biBitCount<=1)
		biBitCount=1;
	else if(biBitCount<=4)
		biBitCount=4;
	else if(biBitCount<=8)
		biBitCount=8;
	else 
		biBitCount=24;

	// 计算调色板的尺寸
	// 如果biClrUsed为零,则用到的颜色数为2的biBitCount次方
	switch(biBitCount) {
		case 1:
			nColorTableEntries = 2;
			break;
		case 4:
			nColorTableEntries = 16;
			break;
		case 8:
			nColorTableEntries = 256;
			break;
		case 16:
		case 24:
		case 32:
			nColorTableEntries = 0;
			break;
		default:
			ASSERT(FALSE);
	}	
	ASSERT((nColorTableEntries >= 0) && (nColorTableEntries <= 256)); 
	m_nColorTableEntries = nColorTableEntries;

	// 分配DIB信息头和调色板的内存
	m_lpBMIH = (LPBITMAPINFOHEADER) new char
		[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries];
	m_nBmihAlloc = m_nImageAlloc = crtAlloc;

	m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER); 
	m_lpBMIH->biWidth = bm.bmWidth; 
	m_lpBMIH->biHeight = bm.bmHeight; 
	m_lpBMIH->biPlanes = 1; 
	m_lpBMIH->biBitCount = biBitCount; 
	m_lpBMIH->biCompression = BI_RGB; 
	m_lpBMIH->biSizeImage = 0; 
	m_lpBMIH->biXPelsPerMeter = 0; 
	m_lpBMIH->biYPelsPerMeter = 0; 
	m_lpBMIH->biClrUsed = nColorTableEntries;
	m_lpBMIH->biClrImportant = nColorTableEntries;	

	// 获得设备上下文句柄
	hDC=GetDC(NULL);
	   
	// 如果没有指定调色板,则从系统中获得当前的系统调色板
	if(hPal==NULL){
		hPal = GetSystemPalette();
	}
	hPal = SelectPalette(hDC, hPal, FALSE); 
	RealizePalette(hDC); 
 

	// 调用GetDIBits填充信息头,并获得图象数据的尺寸。注意这里图象数据指针为NULL
	GetDIBits( hDC, hBitmap, 0, (UINT)m_lpBMIH->biHeight, NULL, (LPBITMAPINFO)m_lpBMIH, DIB_RGB_COLORS);

	// 如果没有正确的获得图象数据尺寸,则重新计算
	if( m_lpBMIH->biSizeImage == 0 ){
		m_lpBMIH->biSizeImage=(((bm.bmWidth*biBitCount) + 31) / 32 * 4)*bm.bmHeight;
	}

	// 分配存放图象数据的内存
	m_lpImage = (LPBYTE) new char[m_lpBMIH->biSizeImage];

	// 调用GetDIBits加载图象数据,注意这里给出了图象数据指针

	// 如果加载图象数据不成功,则释放已经分配的内存,并返回FALSE
	if( GetDIBits( hDC, hBitmap, 0, (UINT)m_lpBMIH->biHeight, (LPBYTE)m_lpImage,
		(LPBITMAPINFO)m_lpBMIH, DIB_RGB_COLORS) == 0 ){
		//clean up and return NULL
		Empty();

		SelectPalette( hDC, hPal, TRUE );
		RealizePalette( hDC );
		ReleaseDC( NULL, hDC );
		
		return FALSE;
	}

	// 删除临时变量
	SelectPalette(hDC, hPal, TRUE); 
	RealizePalette(hDC); 
	ReleaseDC(NULL, hDC); 
	return TRUE;
}

/*************************************************************************
 *
 * \函数名称:
 *   Compress()
 *
 * \输入参数:
 *   CDC*	pDC			- 设备上下文指针
 *   BOOL	bCompress		- TRUE对应于压缩的DIB,FALSE对应于不压缩的DIB
 *
 * \返回值:
 *   BOOL				- 如果成功,则返回TRUE
 *
 * \说明:
 *   该函数将DIB重新生成为压缩或者不压缩的DIB。在内部,它转换已有的DIB为DDB位图
 *   然后生成一个新的压缩或者不压缩的DIB。压缩仅为4bpp和8bpp的DIB所支持。不能
 *   压缩DIB段
 *
 ************************************************************************
 */
BOOL CDib::Compress(CDC* pDC, BOOL bCompress /* = TRUE */)
{
	// 判断是否为4bpp或者8bpp位图,否则,不进行压缩,返回FALSE
	if((m_lpBMIH->biBitCount != 4) && (m_lpBMIH->biBitCount != 8)) return FALSE;
	
	// 如果为DIB段,也不能支持压缩,返回FALSE
	if(m_hBitmap) return FALSE; 

	TRACE("Compress: original palette size = %d\n", m_nColorTableEntries); 
	
	// 获得设备上下文句柄
	HDC hdc = pDC->GetSafeHdc();

	// 将此DIB的调色板选入设备上下文,并保存以前的调色板句柄
	HPALETTE hOldPalette = ::SelectPalette(hdc, m_hPalette, FALSE);

	HBITMAP hBitmap;  

	// 创建一个DDB位图,如果不成功,则返回FALSE
	if((hBitmap = CreateBitmap(pDC)) == NULL) return FALSE;

	// 计算信息头加上调色板的大小尺寸,并给它们分配内存
	int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
	LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];

	// 将信息头和调色板拷贝到内存中
	memcpy(lpBMIH, m_lpBMIH, nSize);  // new header

	// 如果需要进行压缩,设置相应的信息,并创建压缩格式的DIB
	if(bCompress) {
		switch (lpBMIH->biBitCount) {
		case 4:
			lpBMIH->biCompression = BI_RLE4;
			break;
		case 8:
			lpBMIH->biCompression = BI_RLE8;
			break;
		default:
			ASSERT(FALSE);
		}

		// 设置位图数据指针为NULL,调用GetDIBits来得到压缩格式的DIB的尺寸
		// 如果不能创建DIB,则进行相应的错误处理。
		if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,
					NULL, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)) {
			AfxMessageBox("Unable to compress this DIB");			

			// 删除临时变量,并释放已分配内存
	 		::DeleteObject(hBitmap);
			delete [] lpBMIH;

			// 重新将以前的调色板选入,并返回FALSE
			::SelectPalette(hdc, hOldPalette, FALSE);
			return FALSE; 
		}

		// 如果位图数据为空,则进行相应的错误处理
		if (lpBMIH->biSizeImage == 0) {
			AfxMessageBox("Driver can't do compression");

			// 删除临时变量,并释放已分配内存
	 		::DeleteObject(hBitmap);
			delete [] lpBMIH;

			// 重新将以前的调色板选入,并返回FALSE
			::SelectPalette(hdc, hOldPalette, FALSE);
			return FALSE; 
		}

		// 将位图数据尺寸赋值给类的成员变量
		else {
			m_dwSizeImage = lpBMIH->biSizeImage;
		}
	}

	// 如果是解压缩,进行相应的处理
	else {

		// 设置压缩格式为不压缩
		lpBMIH->biCompression = BI_RGB; 

		// 根据位图的宽度和高度计算位图数据内存的大小		
		DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32;
		if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) {
			dwBytes++;
		}
		dwBytes *= 4;
		
		// 将得到位图数据的大小尺寸保存在类的成员变量中
		m_dwSizeImage = dwBytes * lpBMIH->biHeight; 

		// 将位图数据内存的大小赋值给临时的信息头中的相应的变量
		lpBMIH->biSizeImage = m_dwSizeImage;
	} 

	// 再次调用GetDIBits来生成DIB数据

⌨️ 快捷键说明

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