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

📄 dib.cpp

📁 这是一个对24位DIB位图进行行程压缩和解压的程序.功能完全
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ************************************************************************
//	文件名:Dib.cpp
//
//	DIB(Independent Bitmap) 函数库:
//
//	PaintDIB()		- 绘制DIB对象
//	CreateDIBPalette()	- 创建DIB对象调色板
//	FindDIBBits()		- 返回DIB图像象素起始位置
//	DIBWidth()		- 返回DIB宽度
//	DIBHeight()		- 返回DIB高度
//	PaletteSize()		- 返回DIB调色板大小
//	DIBNumColors()		- 计算DIB调色板颜色数目
//	CopyHandle()		- 拷贝内存块
//	DIBBitCount()		- 该函数返回DIBBitCount	
//	SaveDIB()		- 将DIB保存到指定文件中
//	ReadDIBFile()		- 重指定文件中读取DIB对象
//	SetRgnColor()		- 用指定的颜色填充指定的区域
//	SetCircleColor()	- 用指定的颜色填充指定的圆形区域
// ************************************************************************

#include "stdafx.h"
#include "dib.h"
#include <io.h>
#include <errno.h>

#include <math.h>
#include <direct.h>

//Dib文件(*.BMP)头标志(字符串"BM",写DIB时用到该常数)
#define DIB_HEADER_MARKER ((WORD)('M'<< 8) | 'B')

CDIB::CDIB()
{
	
}

CDIB::~CDIB()
{
}

////////////////////////////////////////////////////////////////////////////
//功能模块开始								  //
////////////////////////////////////////////////////////////////////////////

/*************************************************************************
 *
 * 函数名称:
 *   PaintDIB()
 *
 * 参数:
 *   HDC hDC            - 设备环境句柄
 *   LPRECT lpDCRect    - 矩形区域
 *   HDIB hDIB          - 指向DIB对象的指针
 *   LPRECT lpDIBRect   - 待输出DIB区域
 *   CPalette* pPal     - 调色板指针
 *
 * 返回值:
 *   BOOL               - 绘制成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   绘制DIB对象
 *
 ************************************************************************/

BOOL CDIB::PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT  lpDIBRect, CPalette* pPal)
{
	LPBYTE    lpDIBINFOHEADER;			// BITMAPINFOHEADER指针
	LPBYTE    lpDIBBits;				// DIB象素指针
	BOOL	  bRet = FALSE;				// 返回成功标志
	HPALETTE  hNewPal = NULL;			// 当前的调色板
	HPALETTE  hOldPal = NULL;			// 以前的调色板

	// 判断DIB对象是否为空
	if (hDIB == NULL)
	{
		// 返回
		return FALSE;
	}

	// 锁定DIB
	lpDIBINFOHEADER  = (LPBYTE)::GlobalLock((HGLOBAL)hDIB);

	// 找到DIB图像象素起始位置
	lpDIBBits = FindDIBBits(lpDIBINFOHEADER);

	// 获取DIB调色板,并选中
	if (pPal != NULL)
	{
		hNewPal = (HPALETTE) pPal->m_hObject;

		// 选中调色板
		hOldPal = ::SelectPalette(hDC, hNewPal, TRUE);
	}

	// 设置显示模式
	::SetStretchBltMode(hDC, COLORONCOLOR);

	// 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象
	if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
	{
		// 原始大小,不用拉伸。
		bRet = ::SetDIBitsToDevice(hDC, lpDCRect->left,				// DestX
						lpDCRect->top,				// DestY
						RECTWIDTH(lpDCRect),			// nDestWidth
						RECTHEIGHT(lpDCRect),			// nDestHeight
						lpDIBRect->left,			// SrcX
						(int)DIBHeight(lpDIBINFOHEADER) - lpDIBRect->top - RECTHEIGHT(lpDIBRect),	// SrcY
						0,					// nStartScan
						(WORD)DIBHeight(lpDIBINFOHEADER),	// nNumScans
						lpDIBBits,				// lpBits
						(LPBITMAPINFO)lpDIBINFOHEADER,		// lpBitsInfo
						DIB_RGB_COLORS);			// wUsage
	}
	else
	{
		// 非原始大小,拉伸。
		bRet = ::StretchDIBits(hDC, lpDCRect->left,				// DestX
						lpDCRect->top,				// DestY
						RECTWIDTH(lpDCRect),			// nDestWidth
						RECTHEIGHT(lpDCRect),			// nDestHeight
						lpDIBRect->left,			// SrcX
						lpDIBRect->top,				// SrcY
						RECTWIDTH(lpDIBRect),			// wSrcWidth
						RECTHEIGHT(lpDIBRect),			// wSrcHeight
						lpDIBBits,				// lpBits
						(LPBITMAPINFO)lpDIBINFOHEADER,		// lpBitsInfo
						DIB_RGB_COLORS,				// wUsage
						SRCCOPY);				// dwROP
	}
	
	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);
	
	// 恢复以前的调色板
	if (hOldPal != NULL)
	{
		::SelectPalette(hDC, hOldPal, TRUE);
	}
	
	// 返回
	return bRet;
}


/*************************************************************************
 *
 * 函数名称:
 *   CreateDIBPalette()
 *
 * 参数:
 *   HDIB hDIB          - 指向DIB对象的指针
 *   CPalette* pPal     - 调色板指针
 *
 * 返回值:
 *   BOOL               - 创建成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   创建DIB对象调色板
 *
 ************************************************************************/

BOOL CDIB::CreateDIBPalette(HDIB hDIB, CPalette* pPal)
{
	// 指向逻辑调色板的指针
	LPLOGPALETTE lpPal;
	
	// 逻辑调色板的句柄
	HANDLE hLogPal;
	
	// 调色板的句柄
	HPALETTE hPal = NULL;
	
	// 循环变量
	int i;
	
	// 颜色表中的颜色数目
	int nNumColors;
	
	// 指向DIB的指针
	LPBYTE lpbi;
	
	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPINFO lpbmi;
	
	// 指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREINFO lpbmc;
	
	// 表明是否是Win3.0 DIB的标记
	BOOL bWinStyleDIB;
	
	// 创建结果
	BOOL bRet = FALSE;
	
	// 判断DIB是否为空
	if (hDIB == NULL)
	{
		// 返回FALSE
		return FALSE;
	}
	
	// 锁定DIB
	lpbi = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
	
	// 获取指向BITMAPINFO结构的指针(Win3.0)
	lpbmi = (LPBITMAPINFO)lpbi;
	
	// 获取指向BITMAPCOREINFO结构的指针
	lpbmc = (LPBITMAPCOREINFO)lpbi;
	
	// 获取DIB中颜色表中的颜色数目
	nNumColors = DIBNumColors(lpbi);
	
	if (nNumColors != 0)
	{
		// 分配为逻辑调色板内存
		hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nNumColors);
		
		// 如果内存不足,退出
		if (hLogPal == 0)
		{
			// 解除锁定
			::GlobalUnlock((HGLOBAL) hDIB);
			
			// 返回FALSE
			return FALSE;
		}
		
		lpPal = (LPLOGPALETTE)::GlobalLock((HGLOBAL) hLogPal);
		
		// 设置版本号
		lpPal->palVersion = PALVERSION;
		
		// 设置颜色数目
		lpPal->palNumEntries = (WORD)nNumColors;
		
		// 判断是否是WIN3.0的DIB
		bWinStyleDIB = IS_WIN30_DIB(lpbi);

		// 读取调色板
		for (i = 0; i < nNumColors; i++)
		{
			if (bWinStyleDIB)
			{
				// 读取红色分量
				lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
				
				// 读取绿色分量
				lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
				
				// 读取蓝色分量
				lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
				
				// 保留位
				lpPal->palPalEntry[i].peFlags = 0;
			}
			else
			{
				// 读取红色分量
				lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
				
				// 读取绿色分量
				lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
				
				// 读取红色分量
				lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
				
				// 保留位
				lpPal->palPalEntry[i].peFlags = 0;
			}
		}
		
		// 按照逻辑调色板创建调色板,并返回指针
		bRet = pPal->CreatePalette(lpPal);
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hLogPal);
		
		// 释放逻辑调色板
		::GlobalFree((HGLOBAL) hLogPal);
	}
	
	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);
	
	// 返回结果
	return bRet;
}


/*************************************************************************
 *
 * 函数名称:
 *   FindDIBBits()
 *
 * 参数:
 *   LPBYTE lpbi        - 指向DIB对象的指针
 *
 * 返回值:
 *   LPBYTE             - 指向DIB图像象素起始位置
 *
 * 说明:
 *   返回DIB图像象素起始位置
 *
 ************************************************************************/

LPBYTE CDIB::FindDIBBits(LPBYTE lpbi)
{
	return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
}


/*************************************************************************
 *
 * 函数名称:
 *   DIBWidth()
 *
 * 参数:
 *   LPBYTE lpbi        - 指向DIB对象的指针
 *
 * 返回值:
 *   DWORD              - DIB位像宽度
 *
 * 说明:
 *   获取DIB位图的宽度
 *
 ************************************************************************/

DWORD CDIB::DIBWidth(LPBYTE lpDIB)
{
	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPINFOHEADER lpbmi;
	
	// 指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREHEADER lpbmc;

	// 获取指针
	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

	// 返回DIB中图像的宽度
	if (IS_WIN30_DIB(lpDIB))
	{
		// 对于Windows 3.0 DIB,返回lpbmi->biWidth
		return lpbmi->biWidth;
	}
	else
	{
		// 对于其它格式的DIB,返回lpbmc->bcWidth
		return (DWORD)lpbmc->bcWidth;
	}
}


/*************************************************************************
 *
 * 函数名称:
 *   DIBHeight()
 *
 * 参数:
 *   LPBYTE lpDIB       - 指向DIB对象的指针
 *
 * 返回值:
 *   DWORD              - DIB位图高度
 *
 * 说明:
 *   获取DIB位图高度
 *
 ************************************************************************/

DWORD CDIB::DIBHeight(LPBYTE lpDIB)
{
	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPINFOHEADER lpbmi;
	
	// 指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREHEADER lpbmc;

	// 获取指针
	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

	// 返回DIB中图像的宽度
	if (IS_WIN30_DIB(lpDIB))
	{
		// 对于Windows 3.0 DIB,返回lpbmi->biHeight
		return lpbmi->biHeight;
	}
	else
	{
		// 对于其它格式的DIB,返回lpbmc->bcHeight
		return (DWORD)lpbmc->bcHeight;
	}
}


/*************************************************************************
 *
 * 函数名称:
 *   PaletteSize()
 *
 * 参数:
 *   LPBYTE lpbi        - 指向DIB对象的指针
 *
 * 返回值:
 *   WORD               - DIB中调色板的大小
 *
 * 说明:
 *   返回DIB调色板大小
 *
 ************************************************************************/

WORD CDIB::PaletteSize(LPBYTE lpbi)
{
	// 计算DIB中调色板的大小
	if (IS_WIN30_DIB (lpbi))
	{
		//返回颜色数目×RGBQUAD的大小
		return (WORD)(DIBNumColors(lpbi) * sizeof(RGBQUAD));
	}
	else
	{
		//返回颜色数目×RGBTRIPLE的大小
		return (WORD)(DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
	}
}


/*************************************************************************
 *
 * 函数名称:
 *   DIBNumColors()
 *
 * 参数:
 *   LPBYTE lpbi        - 指向DIB对象的指针
 *
 * 返回值:
 *   WORD               - 返回调色板中颜色的种数
 *
 * 说明:
 *   计算DIB调色板颜色数目
 *
 ************************************************************************/

WORD CDIB::DIBNumColors(LPBYTE lpbi)
{
	int nBitCount;

	// 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。

⌨️ 快捷键说明

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