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

📄 gifapi.cpp

📁 vc++数字图像处理 ,是一本很不错的介绍数字图像方面的书籍,这里有本书的全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if (lpGIFCVar->wBlockNdx > 1)	{		// 判断wByteCnt + 256是否超过MAX_BUFF_SIZE		if ((lpGIFCVar->wByteCnt + 256) >= MAX_BUFF_SIZE)		{			// 输出			file.Write(lpGIFCVar->lpDataBuff,						   lpGIFCVar->wByteCnt);			lpGIFCVar->lpEndBuff = lpGIFCVar->lpDataBuff;			lpGIFCVar->wByteCnt  = 0;		}		bySubBlock[0]           = (BYTE)(lpGIFCVar->wBlockNdx - 1);		memcpy(lpGIFCVar->lpEndBuff,(LPSTR)bySubBlock,lpGIFCVar->wBlockNdx);		lpGIFCVar->lpEndBuff   += lpGIFCVar->wBlockNdx;		lpGIFCVar->wByteCnt    += lpGIFCVar->wBlockNdx;		lpGIFCVar->wBlockNdx    = 1;	}		// 解除锁定	GlobalUnlock(hTableNdx);	GlobalUnlock(hPrefix);	GlobalUnlock(hSuffix);		// 释放内存	GlobalFree(hTableNdx);	GlobalFree(hPrefix);	GlobalFree(hSuffix);		// 退出	return;}/************************************************************************* * * 函数名称: *   GIF_LZW_WriteCode() * * 参数: *   CFile& file			- 要保存的文件 *	 WORD wCode				- 要添加的编码 *   LPSTR lpSubBlock		- 子块 *	 LPBYTE lpbyCurrentBits	- 当前位数 *	 LPGIFC_VAR lpGIFCVar	- 指向GIFC_VAR结构的指针 * * 返回值: *   无 * * 说明: *   该函数用来输出一个编码。 * *************************************************************************/void WINAPI GIF_LZW_WriteCode(CFile& file, WORD wCode, LPSTR lpSubBlock,                              LPBYTE lpbyCurrentBits,LPGIFC_VAR lpGIFCVar){	// 输出该编码	lpGIFCVar->dwTempCode |= ((DWORD)wCode << lpGIFCVar->byLeftBits);	lpGIFCVar->byLeftBits += (*lpbyCurrentBits);		while(lpGIFCVar->byLeftBits >= 0x08)	{		lpSubBlock[lpGIFCVar->wBlockNdx++] = (BYTE)lpGIFCVar->dwTempCode;      		// 判断是否超出MAX_SUBBLOCK_SIZE		if (lpGIFCVar->wBlockNdx > MAX_SUBBLOCK_SIZE)		{			// 判断wByteCnt + 256是否超过MAX_BUFF_SIZE			if ((lpGIFCVar->wByteCnt + 256) >= MAX_BUFF_SIZE)			{				// 输出				file.Write(lpGIFCVar->lpDataBuff,							lpGIFCVar->wByteCnt);	            lpGIFCVar->lpEndBuff = lpGIFCVar->lpDataBuff;		        lpGIFCVar->wByteCnt  = 0;			}			lpSubBlock[0]           = (BYTE)(lpGIFCVar->wBlockNdx - 1);			memcpy(lpGIFCVar->lpEndBuff,lpSubBlock,lpGIFCVar->wBlockNdx);			lpGIFCVar->lpEndBuff   += lpGIFCVar->wBlockNdx;			lpGIFCVar->wByteCnt    += lpGIFCVar->wBlockNdx;			lpGIFCVar->wBlockNdx    = 1;		}		lpGIFCVar->dwTempCode >>= 8;		lpGIFCVar->byLeftBits  -= 0x08;	}		// 返回	return;}/************************************************************************* * * 函数名称: *   ReadGIF() * * 参数: *   CFile& file        - 要读取的文件 * * 返回值: *   HDIB               - 成功返回DIB的句柄,否则返回NULL。 * * 说明: *   该函数将读取指定的GIF文件。将读取的结果保存在一个未压缩 * 编码的DIB对象中。 * *************************************************************************/HDIB WINAPI ReadGIF(CFile& file){		// DIB句柄	HDIB			   hDIB;		// DIB指针	LPSTR			   pDIB;		// 指向DIB像素的指针	LPSTR			   lpDIBBits;		// 指向BITMAPINFOHEADER的指针	LPBITMAPINFOHEADER lpBIH;		// 指向BITMAPINFO的指针	LPBITMAPINFO       lpBI;			// GIF文件头	GIFHEADER          GIFH;		// GIF逻辑屏幕描述块	GIFSCRDESC         GIFS;		// GIF图像描述块	GIFIMAGE           GIFI;		// GIF图像控制扩充块	GIFCONTROL         GIFC;		// GIF图像说明扩充块	GIFPLAINTEXT       GIFP;		// GIF应用程序扩充块	GIFAPPLICATION     GIFA;		// GIF编码参数	GIFD_VAR           GIFDVar;		// 颜色数目	WORD               wColors;		// 每行字节数	WORD               wWidthBytes;		// 调色板	BYTE               byGIF_Pal[768];		// 16色系统调色板	BYTE               bySysPal16[48] = {	0,   0,   0,   0,   0, 128,											0, 128,   0,   0, 128, 128,										  128,   0,   0, 128,   0, 128,										  128, 128,   0, 128, 128, 128,										  192, 192, 192,   0,   0, 255,											0, 255,   0,   0, 255, 255,										  255,   0,   0, 255,   0, 255,										  255, 255,   0, 255, 255, 255									   };		// DIB大小(字节数)	DWORD              dwDIB_Size;			// 调色板大小(字节数)	WORD               wPalSize;		// 字节变量	BYTE               byTemp;		// 内存句柄	HANDLE			   hSrcBuff;	HANDLE             hTemp;		// 内存指针	LPSTR              lpTemp;		// 字变量	WORD               wTemp;		// 循环变量	WORD               wi;		// 标签	BYTE               byLabel;		// 块大小	BYTE               byBlockSize;		// 读取GIF文件头	file.Read((LPSTR)&GIFH, sizeof(GIFH));		// 判断是否是GIF文件	if (memicmp((LPSTR)GIFH.bySignature,"GIF",3) != 0)	{		// 非GIF文件,返回NULL		return NULL;	}		// 判断版本号是否正确	if ((memicmp((LPSTR)GIFH.byVersion,"87a",3) != 0) &&		(memicmp((LPSTR)GIFH.byVersion,"89a",3) != 0))	{		// 不支持该版本,返回NULL		return NULL;	}		// 读取GIF逻辑屏幕描述块	file.Read((LPSTR)&GIFS, 7);		// 获取调色板的位数	GIFDVar.wBits = (WORD)GIFS.GlobalFlag.PalBits + 1;		// 判断是否有全局调色板	if (GIFS.GlobalFlag.GlobalPal)	{		// 赋初值		memset((LPSTR)byGIF_Pal,0,768);				// 全局调色板大小		wPalSize = 3 * (1 << GIFDVar.wBits);				// 读取全局调色板		file.Read((LPSTR)byGIF_Pal,wPalSize);	}		// 读取下一个字节	file.Read((LPSTR)&byTemp,1);		// 对每一个描述块循环	while(TRUE)	{		// 判断是否是图像描述块		if (byTemp == 0x2C)		{			// 是图像描述块,退出循环			break;		}				// 判断是否是GIF扩展块		if (byTemp==0x21)		{			// 是GIF扩展块						// 分配内存			hTemp  = GlobalAlloc(GHND,(DWORD)MAX_BUFF_SIZE);						// 锁定内存			lpTemp = (LPSTR) GlobalLock(hTemp);						// 读取下一个字节			file.Read((LPSTR)&byLabel, 1);						// 针对各种扩充块,进行分别处理			switch(byLabel)			{				case 0xF9:				{					// 图像控制扩充块					file.Read((LPSTR)&GIFC, 6);										// 跳出					break;				}				case 0x01:				{					// 图像说明扩充块					file.Read((LPSTR)&GIFP,sizeof(GIFP));										// 读取扩充块大小					file.Read((LPSTR)&byBlockSize,1);										// 当byBlockSize > 0时循环读取					while(byBlockSize)					{						// 读取图像说明扩充块(这里没有进行任何处理)						file.Read(lpTemp,byBlockSize);												// 读取扩充块大小						file.Read((LPSTR)&byBlockSize,1);					}										// 跳出					break;				}				case 0xFE:				{					// 注释说明扩充块										// 读取扩充块大小					file.Read((LPSTR)&byBlockSize,1);										// 当byBlockSize > 0时循环读取					while(byBlockSize)					{						// 读取注释说明扩充块(这里没有进行任何处理)						file.Read(lpTemp,byBlockSize);											// 读取扩充块大小						file.Read((LPSTR)&byBlockSize,1);					}										// 跳出					break;				}				case 0xFF:				{					// 应用程序扩充块					file.Read((LPSTR)&GIFA, sizeof(GIFA));										// 读取扩充块大小					file.Read((LPSTR)&byBlockSize,1);										// 当byBlockSize > 0时循环读取					while(byBlockSize)					{						// 读取应用程序扩充块(这里没有进行任何处理)						file.Read(lpTemp,byBlockSize);												// 读取扩充块大小						file.Read((LPSTR)&byBlockSize,1);					}										// 跳出					break;				}				default:				{					// 忽略未知的扩充块										// 读取扩充块大小					file.Read((LPSTR)&byBlockSize,1);										// 当byBlockSize > 0时循环读取					while(byBlockSize)					{						// 读取未知的扩充块(这里没有进行任何处理)						file.Read(lpTemp,byBlockSize);												// 读取扩充块大小						file.Read((LPSTR)&byBlockSize,1);					}										// 跳出					break;				}							// 释放内存				GlobalUnlock(hTemp);				GlobalFree(hTemp);			}		}				// 读取下一个字节		file.Read((LPSTR)&byTemp,1);	}	// 读取GIF图像描述块	file.Read((LPSTR)&GIFI, 9);		// 获取图像宽度	GIFDVar.wWidth         = GIFI.wWidth;		// 获取图像高度	GIFDVar.wDepth         = GIFI.wDepth;		// 判断是否有区域调色板	if (GIFI.LocalFlag.LocalPal)	{		// 赋初值		memset((LPSTR)byGIF_Pal, 0, 768);				// 读取区域调色板位数		GIFDVar.wBits = (WORD)GIFI.LocalFlag.PalBits + 1;				// 区域调色板大小		wPalSize      = 3 * (1 << GIFDVar.wBits);				// 读取区域调色板		file.Read((LPSTR)byGIF_Pal,wPalSize);	}		// 给GIFDVar成员赋值	GIFDVar.wBits          = ((GIFDVar.wBits==1) ? 1 :							  (GIFDVar.wBits<=4) ? 4 : 8);		GIFDVar.wLineBytes     = (WORD)BYTE_WBYTES((DWORD)GIFDVar.wWidth *											   (DWORD)GIFDVar.wBits);	GIFDVar.bEOF           = FALSE;		// 交错方式	GIFDVar.bInterlace     = (GIFI.LocalFlag.Interlace ? TRUE : FALSE);		// 每行字节数	wWidthBytes			   = (WORD)DWORD_WBYTES((DWORD)GIFDVar.wWidth *								  				(DWORD)GIFDVar.wBits);		// 颜色数目	wColors				   = 1 << GIFDVar.wBits;		// 调色板大小	wPalSize			   = wColors * sizeof(RGBQUAD);		// 计算DIB长度(字节)	dwDIB_Size			   = sizeof(BITMAPINFOHEADER) + wPalSize							 + GIFDVar.wDepth * wWidthBytes;		// 为DIB分配内存	hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIB_Size);		if (hDIB == 0)	{		// 内存分配失败,返回NULL。		return NULL;	}		// 锁定	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);		///////////////////////////////////////////////////////////////////////////	// 设置BITMAPINFOHEADER		// 赋值	lpBIH = (LPBITMAPINFOHEADER) pDIB;	lpBI  = (LPBITMAPINFO) pDIB;		// 给lpBIH成员赋值	lpBIH->biSize = (DWORD)sizeof(BITMAPINFOHEADER);	lpBIH->biWidth = (DWORD)GIFDVar.wWidth;	lpBIH->biHeight = (DWORD)GIFDVar.wDepth;	lpBIH->biPlanes = 1;	lpBIH->biBitCount = GIFDVar.wBits;	lpBIH->biCompression = BI_RGB;	lpBIH->biSizeImage = (DWORD)wWidthBytes * GIFDVar.wDepth;	lpBIH->biXPelsPerMeter = 0;	lpBIH->biYPelsPerMeter = 0;	lpBIH->biClrUsed = wColors;	lpBIH->biClrImportant = 0;		///////////////////////////////////////////////////////////////////////////	// 设置调色板		// 判断是否指定全局或区域调色板	if (GIFS.GlobalFlag.GlobalPal || GIFI.LocalFlag.LocalPal)	{		wTemp = 0;		for(wi=0; wi<wColors; wi++)		{			lpBI->bmiColors[wi].rgbRed      = byGIF_Pal[wTemp++];			lpBI->bmiColors[wi].rgbGreen    = byGIF_Pal[wTemp++];			lpBI->bmiColors[wi].rgbBlue     = byGIF_Pal[wTemp++];			lpBI->bmiColors[wi].rgbReserved = 0x00;		}	}	else	{		// 没有指定全局和区域调色板,采用系统调色板				// 按照颜色数目来分别给调色板赋值		switch(wColors)		{			case   2:			{				// 单色位图								lpBI->bmiColors[0].rgbRed          = 0x00;				lpBI->bmiColors[0].rgbGreen        = 0x00;				lpBI->bmiColors[0].rgbBlue         = 0x00;				lpBI->bmiColors[0].rgbReserved     = 0x00;				lpBI->bmiColors[1].rgbRed          = 0xFF;				lpBI->bmiColors[1].rgbGreen        = 0xFF;				lpBI->bmiColors[1].rgbBlue         = 0xFF;				lpBI->bmiColors[1].rgbReserved     = 0x00;								// 跳出				break;			}			case  16:			{				// 16色位图								wTemp = 0;				for(wi=0;wi<wColors;wi++)				{					lpBI->bmiColors[wi].rgbRed      = bySysPal16[wTemp++];					lpBI->bmiColors[wi].rgbGreen    = bySysPal16[wTemp++];					lpBI->bmiColors[wi].rgbBlue     = bySysPal16[wTemp++];					lpBI->bmiColors[wi].rgbReserved = 0x00;				}								// 跳出				break;			}			case 256:			{				// 256色位图				for(wi=0; wi<wColors; wi++)				{					lpBI->bmiColors[wi].rgbRed      = (BYTE)wi;					lpBI->bmiColors[wi].rgbGreen    = (BYTE)wi;					lpBI->bmiColors[wi].rgbBlue     = (BYTE)wi;					lpBI->bmiColors[wi].rgbReserved = 0x00;				}								// 跳出				break;			}		}	}		///////////////////////////////////////////////////////////////////////////	// 解码	// 获取编码数据长度	GIFDVar.dwDataLen  = (DWORD) (file.GetLength() - file.GetPosition());		// 计算内存大小(最大不超过MAX_BUFF_SIZE)	GIFDVar.wMemLen    = ((GIFDVar.dwDataLen > (DWORD)MAX_BUFF_SIZE) ?						  (WORD)MAX_BUFF_SIZE : (WORD)GIFDVar.dwDataLen);		// 分配内存	hSrcBuff = GlobalAlloc(GHND, (DWORD)GIFDVar.wMemLen);		// 锁定内存	GIFDVar.lpDataBuff = (LPSTR)GlobalLock(hSrcBuff);		// 读取编码数据	ReadSrcData(file,&GIFDVar.wMemLen,&GIFDVar.dwDataLen,				GIFDVar.lpDataBuff,&GIFDVar.bEOF);		// 缓冲区起始位置	GIFDVar.lpBgnBuff  = GIFDVar.lpDataBuff;		// 缓冲区中止位置	GIFDVar.lpEndBuff  = GIFDVar.lpBgnBuff + GIFDVar.wMemLen;		// 计算DIB中像素位置	lpDIBBits = (LPSTR) FindDIBBits(pDIB);		// 解码	DecodeGIF_LZW(file, lpDIBBits, &GIFDVar, wWidthBytes);	// 释放内存	GlobalUnlock(hSrcBuff);	GlobalFree(hSrcBuff);		// 返回DIB句柄	return hDIB;}/************************************************************************* * * 函数名称: *   ReadSrcData()

⌨️ 快捷键说明

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