www.pudn.com > ScanDlg.rar > SckLzw.h


///////////////////////////////////////////////////////////////////////////// 
//                                                                         // 
//         用途 : LZW For GIF 压缩算法                                     // 
//         创建 : [Sck007] / 2003-03-30                                    // 
//         更新 : 2003-08-18                                               // 
//         主页 : www.tcsy.net                                             // 
//         邮箱 : sck007@163.com                                           // 
//                                     (c) 1996 - 2008 =TCSY= 单成坤       // 
///////////////////////////////////////////////////////////////////////////// 
#ifndef  __SCK_LZW_COMPRESS_H__ 
#define  __SCK_LZW_COMPRESS_H__ 
#pragma once 
 
// 编码程序只用到Hash表, 不需要String Table(编码表), 因为它不需要知道 
// String Table中的内容。只需要知道wPrefix + wSuffix字串是否在表中和表中的index 
#define LZW_MAX_TABLE_SIZE  0x1000    // String Table(编码表)的最大长度 (12_Bit) 
 
// Hash表设计为:  (Prefix << 8) + Suffix 中存放的是String Table的Index 
#define LZW_MAX_HASH_SIZE   0x1000FF  // (0x1000 << 8) + 0xFF (20_Bit) 
 
#define LZW_MIN_CODE_LEN    8         // 最小代码长度 
#define LZW_CLEAR           0x100     // Clear字典重置(256) 
#define LZW_END             0x101     // End编码结束(257) 
 
//=========================================================================== 
// LZW - 压缩算法类 - Sck007 
//=========================================================================== 
class CSckLzw 
{ 
private: 
 
	// 解码程序要用到String Table - String 结构节点 
	// 每个String可以形成一棵二叉树, 此二叉树仅有一个右节点 
	// 因为wPrefix总是指向String Table中的另一位置, 而wSuffix指向0 ~ (Clear - 1) 
	typedef struct tagLZW_STRING 
	{ 
		WORD    wPrefix;              // 前缀:Old 
		WORD    wSuffix;              // 后缀:Old/Code 
	} 
	LZW_STRING, *PLZW_STRING; 
 
	const BYTE *m_pCurrIn;            // 输入流当前位置 
	BYTE *m_pCurrOut;                 // 输出流当前位置 
	BYTE m_byCurrBits;                // 当前阶段码长:从9位开始编码 
	WORD m_wTableIndex;               // 当前的String Table(编码表) Index 
 
	void Encode_WriteIndexOut(DWORD dwIndex, BYTE &byOutBit); 
	WORD Decode_GetNextCode(BYTE &byInBit); 
	void Decode_WriteStringOut(LZW_STRING * pString, WORD wPrefix, DWORD &dwCurrPixel); 
 
public: 
 
	DWORD LZW_Encode(const BYTE *InBuffer, DWORD dwLength, BYTE *OutBuffer); 
	DWORD LZW_Decode(const BYTE *InBuffer, BYTE *OutBuffer); 
}; 
 
// 压缩写String Index,最长为12位(4096,最多跨越2_BYTE)。有预留内存,须预清零 
inline void CSckLzw::Encode_WriteIndexOut(DWORD dwIndex, BYTE &byOutBit) 
{ 
	*((DWORD *)m_pCurrOut) |= (dwIndex << byOutBit); // 输出压缩数据 
	register UINT dwSumAdd = m_byCurrBits + byOutBit;// 需要偏移数量 
	m_pCurrOut += dwSumAdd / 8;                      // 直接跨越字节 
	byOutBit   = dwSumAdd % 8;                       // 下次移位数量 
} 
 
// 与写入String Index是相对应的, 最长为12位(最多跨越2-BYTE) 
inline WORD CSckLzw::Decode_GetNextCode(BYTE &byInBit) 
{ 
	register DWORD dwRet    = 0; 
	register UINT  dwSumAdd = m_byCurrBits + byInBit;// 码长至少为9 
 
	if(dwSumAdd <= 8)                                // 在当前BYTE内 
		dwRet |= *m_pCurrIn; 
	else if(dwSumAdd <= 16)                          // 跨越1-BYTE 
		dwRet |= *((WORD *)m_pCurrIn); 
	else                                             // 跨越2-BYTE 
	{ 
		dwRet |= *(m_pCurrIn + 2); 
		dwRet <<= 16; 
		dwRet |= *((WORD *)m_pCurrIn);               // 延伸的处理 
	} 
 
	m_pCurrIn += dwSumAdd / 8;                       // 跨越字节数 
	byInBit    = dwSumAdd % 8; 
	dwRet <<= 32 - dwSumAdd; 
	dwRet >>= 32 - m_byCurrBits;                     // 左右的清零 
	return (WORD)dwRet; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
#endif