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

📄 gifapi.cpp

📁 vc++数字图像处理 ,是一本很不错的介绍数字图像方面的书籍,这里有本书的全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 * * 参数: *   CFile& file			- 源GIF文件 *   LPWORD lpwMemLen		- 缓冲区长度(指针) *   LPDWORD lpdwDataLen	- 剩余数据长度(指针) *   LPSTR lpSrcBuff		- 缓冲区指针 *	 LPBOOL lpbEOF			- 结束标志 * * 返回值: *   无 * * 说明: *   该函数用来读取指定GIF文件中的图像编码,每次最多读取MAX_BUFF_SIZE * 字节,是否读完由标志lpbEOF指定。 * *************************************************************************/void WINAPI ReadSrcData(CFile& file, LPWORD lpwMemLen, LPDWORD lpdwDataLen,                        LPSTR lpSrcBuff, LPBOOL lpbEOF){	// 判断数据长度是否仍然大于内存大小	if ((*lpdwDataLen) > (DWORD)(*lpwMemLen))	{		// 数据长度大于内存大小,表示没有解码完				// 数据长度减内存大小		(*lpdwDataLen) -= (DWORD)(*lpwMemLen);	}	else	{		// 数据长度不大于内存大小,表示解码将要完成				// 内存大小就是剩余数据长度		(*lpwMemLen)    = (WORD)(*lpdwDataLen);				// EOF标志设置为TRUE		(*lpbEOF)       = TRUE;	}		// 读取编码数据	file.Read(lpSrcBuff, (*lpwMemLen));		// 返回	return;}/************************************************************************* * * 函数名称: *   DecodeGIF_LZW() * * 参数: *   CFile& file			- 源GIF文件 *   LPSTR lpDIBBits		- 指向要保存的DIB图像指针 *   LPGIFD_VAR lpGIFDVar	- 指向GIFC_VAR结构的指针 *	 WORD wWidthBytes		- 每行图像字节数 * * 返回值: *   无 * * 说明: *   该函数对指定GIF_LZW编码数据进行解码。 * *************************************************************************/void WINAPI DecodeGIF_LZW(CFile& file, LPSTR lpDIBBits,						  LPGIFD_VAR lpGIFDVar,WORD wWidthBytes){	// 指向编码后图像数据的指针	BYTE *	lpDst;		// 内存分配句柄	HANDLE hPrefix;	HANDLE hSuffix;	HANDLE hStack;	HANDLE hImage;		// 用于字串表搜索的索引	LPWORD lpwPrefix;	LPBYTE lpbySuffix;	LPBYTE lpbyStack;	LPBYTE lpbyStackBgn;		// 指向图像当前行解码结果的指针	LPSTR  lpImageBgn;		// 指向当前编码像素的指针	LPSTR  lpImage;		// 计算当前数据图像的偏移量	DWORD  dwDataNdx;		// LZW_CLEAR	WORD   wLZW_CLEAR;		// LZW_EOI	WORD   wLZW_EOI;		// LZW_MinCodeLen	BYTE   byLZW_MinCodeLen;		// 字串表索引	WORD   wNowTableNdx;	WORD   wTopTableNdx;		// 当前图像的行数	WORD   wRowNum;		// 计数	WORD   wWidthCnt;	WORD   wBitCnt;	WORD   wRowCnt;		// 循环变量	WORD   wi;		// 交错方式存储时每次增加的行数	WORD   wIncTable[5]  = { 8,8,4,2,0 }; 		// 交错方式存储时起始行数	WORD   wBgnTable[5]  = { 0,4,2,1,0 }; 		// 块大小	BYTE   byBlockSize;		// 块索引	BYTE   byBlockNdx;		DWORD  dwData;		// 当前编码	WORD   wCode;		// 上一个编码	WORD   wOldCode;		// 临时索引	WORD   wTempNdx;		WORD   wCodeMask[13] = {0x0000,							0x0001,0x0003,0x0007,0x000F,							0x001F,0x003F,0x007F,0x00FF,							0x01FF,0x03FF,0x07FF,0x0FFF							};		BYTE   byLeftBits;	BYTE   byFirstChar;	BYTE   byCode;	BYTE   byCurrentBits;	BYTE   byPass;		// 临时字节变量	BYTE   byTempChar;		// 给字串表分配内存	hPrefix          = GlobalAlloc(GHND,(DWORD)(MAX_TABLE_SIZE<<1));	hSuffix          = GlobalAlloc(GHND,(DWORD)MAX_TABLE_SIZE);	hStack           = GlobalAlloc(GHND,(DWORD)MAX_TABLE_SIZE);	hImage           = GlobalAlloc(GHND,(DWORD)wWidthBytes);		// 锁定内存	lpwPrefix        = (LPWORD)GlobalLock(hPrefix);	lpbySuffix       = (LPBYTE)GlobalLock(hSuffix);	lpbyStack        = (LPBYTE)GlobalLock(hStack);	lpbyStackBgn     = lpbyStack;	lpImage          = (LPSTR)GlobalLock(hImage);	lpImageBgn       = lpImage;		// 读取GIF LZW最小编码大小	byLZW_MinCodeLen = *lpGIFDVar->lpBgnBuff++;		byCurrentBits    = byLZW_MinCodeLen + (BYTE)0x01;		// 计算LZW_CLEAR	wLZW_CLEAR       = 1 << byLZW_MinCodeLen;		// 计算LZW_EOI	wLZW_EOI         = wLZW_CLEAR + 1;		// 计算字串表索引	wNowTableNdx     = wLZW_CLEAR + 2;	wTopTableNdx     = 1 << byCurrentBits;		// 赋初值	dwData           = 0UL;	wBitCnt          = lpGIFDVar->wBits;	wRowNum          = 0;	wRowCnt          = 1;	wWidthCnt        = 0;	wCode            = 0;	wOldCode         = 0xFFFF;	byBlockSize      = 0x01;	byBlockNdx       = 0x00;	byLeftBits       = 0x00;	byTempChar       = 0x00;	byPass           = 0x00;		// 读取下一个编码	while(byLeftBits < byCurrentBits)	{		// 读取下一个字符				// 判断是否读完一个数据块		if (++byBlockNdx == byBlockSize)		{			// 读取下一个数据块			byBlockSize = *lpGIFDVar->lpBgnBuff++;			byBlockNdx  = 0x00;						// 判断是否读完			if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&			    !lpGIFDVar->bEOF)			{				// 读取下一个数据块				ReadSrcData(file,&lpGIFDVar->wMemLen,							&lpGIFDVar->dwDataLen,							lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);								// 指针重新赋值				lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;				lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;			}		}				// 下一个字符		byCode      = *lpGIFDVar->lpBgnBuff++;				// 移位		dwData     |= ((DWORD)byCode << byLeftBits);		byLeftBits += 0x08;				// 判断是否读完		if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&		    !lpGIFDVar->bEOF)		{			// 读取下一个数据块			ReadSrcData(file,&lpGIFDVar->wMemLen,						&lpGIFDVar->dwDataLen,						lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);						// 指针重新赋值			lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;			lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;		}	}		wCode       = (WORD)dwData & wCodeMask[byCurrentBits];	dwData    >>= byCurrentBits;	byLeftBits -= byCurrentBits;		// 解码	while(wCode != wLZW_EOI)	{		// 当前编码不是LZW_EOI码				// 判断是否是LZW_CLEAR码		if (wCode == wLZW_CLEAR)		{			// 是LZW_CLEAR,清除字串表						// 重新初始化字串表			for(wi = 0; wi < wLZW_CLEAR; wi++)			{				*(lpwPrefix  + wi)  = 0xFFFF;				*(lpbySuffix + wi) = (BYTE)wi;			}						for(wi = wNowTableNdx; wi < MAX_TABLE_SIZE; wi++)			{				*(lpwPrefix+wi)  = 0xFFFF;				*(lpbySuffix+wi) = 0x00;			}						byCurrentBits = byLZW_MinCodeLen + (BYTE)0x01;			wNowTableNdx  = wLZW_CLEAR + 2;			wTopTableNdx  = 1 << byCurrentBits;			wOldCode      = 0xFFFF;						// 获取下一个编码			while(byLeftBits < byCurrentBits)			{				// 读取下一个字符								// 判断是否读完一个数据块				if (++byBlockNdx == byBlockSize)				{					// 读取下一个数据块					byBlockSize = *lpGIFDVar->lpBgnBuff++;					byBlockNdx  = 0x00;										// 判断是否读完					if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&						!lpGIFDVar->bEOF)					{						// 读取下一个数据块						ReadSrcData(file, &lpGIFDVar->wMemLen,									&lpGIFDVar->dwDataLen,									lpGIFDVar->lpDataBuff,									&lpGIFDVar->bEOF);												// 指针重新赋值						lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;						lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff +											   lpGIFDVar->wMemLen;					}				}				byCode      = *lpGIFDVar->lpBgnBuff++;				dwData     |= ((DWORD)byCode << byLeftBits);				byLeftBits += 0x08;								// 判断是否读完				if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&					 !lpGIFDVar->bEOF)				{					// 读取下一个数据块					ReadSrcData(file,&lpGIFDVar->wMemLen,								&lpGIFDVar->dwDataLen,								lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);										// 指针重新赋值					lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;					lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;				}			}			wCode       = (WORD)dwData & wCodeMask[byCurrentBits];			dwData    >>= byCurrentBits;			byLeftBits -= byCurrentBits;						// 判断编码是否为LZW_EOI			if (wCode!=wLZW_EOI)			{				// 这里没有用到lpbyStack[0]				lpbyStack  ++;								// 将数据压入堆栈				while((*(lpwPrefix+wCode)) != 0xFFFF)				{					*lpbyStack++ = *(lpbySuffix+wCode);					wCode        = *(lpwPrefix+wCode);				}				*lpbyStack  = *(lpbySuffix+wCode);				byFirstChar = *lpbyStack;								// 输出数据				while(lpbyStack>lpbyStackBgn)				{					byTempChar |= (*lpbyStack-- << (8-wBitCnt));										if (wBitCnt==8)					{						*lpImage++ = byTempChar;						byTempChar = 0x00;						wBitCnt    = lpGIFDVar->wBits;					}					else					{						wBitCnt   += lpGIFDVar->wBits;					}										wWidthCnt  ++;										if (wWidthCnt==lpGIFDVar->wWidth)					{						if (wBitCnt!=lpGIFDVar->wBits)						{							*lpImage   = byTempChar;							byTempChar = 0x00;							wBitCnt    = lpGIFDVar->wBits;						}												// 图像当前行偏移量						dwDataNdx = (DWORD)(lpGIFDVar->wDepth - 1 - wRowNum) * (DWORD)wWidthBytes;												// 图像当前行起始位置						lpDst = (BYTE *)lpDIBBits + dwDataNdx;												// 赋值						memcpy(lpDst, lpImageBgn, wWidthBytes);												lpImage   = lpImageBgn;												// 判断是否按照交错方式保存						if (lpGIFDVar->bInterlace)						{							// 交错方式														// 计算下一行的行号							wRowNum += wIncTable[byPass];							if (wRowNum >= lpGIFDVar->wDepth)							{								byPass ++;								wRowNum = wBgnTable[byPass];							}						}						else						{							// 非交错方式,行号直接加1							wRowNum ++;						}						wWidthCnt = 0;					}				}			}		}		else		{			// 这里没有用到lpbyStack[0]			lpbyStack  ++;						// 判断字符串是否在字串表中			if (wCode < wNowTableNdx)			{				// 不在字串表中				wTempNdx   = wCode;			}			else			{				// 在字串表中				wTempNdx     = wOldCode;				*lpbyStack++ = byFirstChar;			}						// 将数据压入堆栈			while((*(lpwPrefix+wTempNdx)) != 0xFFFF)			{				*lpbyStack++ = *(lpbySuffix+wTempNdx);				wTempNdx     = *(lpwPrefix+wTempNdx);			}			*lpbyStack  = *(lpbySuffix+wTempNdx);			byFirstChar = *lpbyStack;						// 将字符串添加到字串表中			*(lpwPrefix+wNowTableNdx)  = wOldCode;			*(lpbySuffix+wNowTableNdx) = byFirstChar;			if (++wNowTableNdx==wTopTableNdx && byCurrentBits<12)			{				byCurrentBits ++;				wTopTableNdx   = 1 << byCurrentBits;			}						// 输出数据			while(lpbyStack>lpbyStackBgn)			{				byTempChar |= (*lpbyStack-- << (8-wBitCnt));				if (wBitCnt==8)				{					*lpImage++ = byTempChar;					byTempChar = 0x00;					wBitCnt    = lpGIFDVar->wBits;				}				else				{					wBitCnt   += lpGIFDVar->wBits;				}								wWidthCnt  ++;				if (wWidthCnt==lpGIFDVar->wWidth)				{					if (wBitCnt!=lpGIFDVar->wBits)					{						*lpImage   = byTempChar;						byTempChar = 0x00;						wBitCnt    = lpGIFDVar->wBits;					}										// 图像当前行偏移量					dwDataNdx = (DWORD)(lpGIFDVar->wDepth - 1 - wRowNum) * (DWORD)wWidthBytes;										// 图像当前行起始位置					lpDst = (BYTE *)lpDIBBits + dwDataNdx;										// 赋值					memcpy(lpDst, lpImageBgn, wWidthBytes);										lpImage   = lpImageBgn;										// 判断是否按照交错方式保存					if (lpGIFDVar->bInterlace)					{						// 交错方式												// 计算下一行的行号						wRowNum += wIncTable[byPass];						if (wRowNum >= lpGIFDVar->wDepth)						{							byPass ++;							wRowNum = wBgnTable[byPass];						}					}					else					{						// 非交错方式,行号直接加1						wRowNum ++;					}					wWidthCnt = 0;				}			}		}		wOldCode = wCode;				// 读取下一个编码		while(byLeftBits < byCurrentBits)		{			// 读取下一个字符						// 判断是否读完一个数据块			if (++byBlockNdx == byBlockSize)			{				// 读取下一个数据块				byBlockSize = *lpGIFDVar->lpBgnBuff++;				byBlockNdx  = 0x00;								// 判断是否读完				if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&					 !lpGIFDVar->bEOF)				{					// 读取下一个数据块					ReadSrcData(file,&lpGIFDVar->wMemLen,								&lpGIFDVar->dwDataLen,								lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);										// 指针重新赋值					lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;					lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;				}			}			byCode      = *lpGIFDVar->lpBgnBuff++;			dwData     |= ((DWORD)byCode << byLeftBits);			byLeftBits += 0x08;						// 判断是否读完			if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&				  !lpGIFDVar->bEOF)			{				// 读取下一个数据块				ReadSrcData(file,&lpGIFDVar->wMemLen,							&lpGIFDVar->dwDataLen,							lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);								// 指针重新赋值				lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;				lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;			}		}		wCode       = (WORD)dwData & wCodeMask[byCurrentBits];		dwData    >>= byCurrentBits;		byLeftBits -= byCurrentBits;	}		// 释放内存	GlobalUnlock(hPrefix);	GlobalUnlock(hSuffix);	GlobalUnlock(hStack);	GlobalFree(hPrefix);	GlobalFree(hSuffix);	GlobalFree(hStack);		// 返回	return;}

⌨️ 快捷键说明

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