📄 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -