📄 scklzw.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// SckLzw.cpp LZW For GIF 编码和解码实现文件 //
// CopyRight(C) 1996,2008 TCSY 公司 //
// Pentium Working Room ShanChengKun 2003.08.18 更新 //
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SckLzw.h"
//===========================================================================
// 通用LZW编码,编码阶段不需要String Table,只需要m_wTableIndex来获知写位数
//===========================================================================
DWORD CSckLzw::LZW_Encode(const BYTE *InBuffer, // 输入数据流
DWORD dwLength, // 原数据大小
BYTE *OutBuffer) // 压缩后数据
{
WORD *pHash = new WORD [LZW_MAX_HASH_SIZE]; // Hash索引表
if(!pHash || !InBuffer || !OutBuffer) {if(pHash) delete[] pHash; return 0;}
memset(pHash, 0x00, LZW_MAX_HASH_SIZE * sizeof(WORD)); // Hash Table置位0
memset(OutBuffer, 0x00, dwLength * 2 + 2048); // 目标全部清零
m_wTableIndex = LZW_END + 1; // 初始化字符表
m_byCurrBits = LZW_MIN_CODE_LEN + 1; // 当前阶段码长
m_pCurrIn = InBuffer; // 原始输入当前
m_pCurrOut = OutBuffer; // 当前指针输出
DWORD dwCurrPixel = 0, dwHashIndex = 0; // 当前写入点数
BYTE byOutBit = 0; // 输出缓冲位置
WORD wPrefix = m_pCurrIn[dwCurrPixel++]; // Hash索引前缀
WORD wSuffix = 0; // Hash索引后缀
Encode_WriteIndexOut(LZW_CLEAR, byOutBit); // 写Clear首字节
while(dwCurrPixel < dwLength)
{
wSuffix = m_pCurrIn[dwCurrPixel++]; // 提取当前数据
dwHashIndex = (wPrefix << 8) | wSuffix; // 构造Hash地址
// 已在表中,取出索引, Hash Table中存放的是String Table的Index
if (pHash[dwHashIndex] != 0) // 编码可匹配
{
wPrefix = pHash[dwHashIndex]; // 取出索引值
}
// 不在表中,把wPrefix + wSuffix添加到String Table中
else // 没有则添加
{
Encode_WriteIndexOut(wPrefix, byOutBit);
pHash[dwHashIndex] = m_wTableIndex++;
wPrefix = wSuffix;
if ((m_wTableIndex == 0x009) || (m_wTableIndex == 0x011) ||
(m_wTableIndex == 0x021) || (m_wTableIndex == 0x041) ||
(m_wTableIndex == 0x081) || (m_wTableIndex == 0x101) ||
(m_wTableIndex == 0x201) || (m_wTableIndex == 0x401) ||
(m_wTableIndex == 0x801))
m_byCurrBits++;
// String Table(编码表)已经填满
else if (m_wTableIndex == LZW_MAX_TABLE_SIZE)
{
Encode_WriteIndexOut (wSuffix, byOutBit);
Encode_WriteIndexOut (LZW_CLEAR, byOutBit);
m_wTableIndex = LZW_END + 1;
m_byCurrBits = LZW_MIN_CODE_LEN + 1;
memset(pHash, 0x00, LZW_MAX_HASH_SIZE * sizeof(WORD));
wPrefix = m_pCurrIn[dwCurrPixel++];
}
}
}
Encode_WriteIndexOut (wPrefix, byOutBit);
Encode_WriteIndexOut (LZW_END, byOutBit);
delete[] pHash; pHash = NULL;
return (m_pCurrOut - OutBuffer + 1); // 释放并返回
}
//===========================================================================
// 解码到目标8位色位图,目标为8位色,自身递归调用
//===========================================================================
void CSckLzw::Decode_WriteStringOut(LZW_STRING * pString, WORD wPrefix, DWORD &dwCurrPixel)
{
if(wPrefix < LZW_CLEAR)
{
m_pCurrOut[dwCurrPixel++] = (BYTE)pString[wPrefix].wSuffix;
}
else
{
Decode_WriteStringOut(pString, pString[wPrefix].wPrefix, dwCurrPixel);
Decode_WriteStringOut(pString, pString[wPrefix].wSuffix, dwCurrPixel);
}
}
//===========================================================================
// 通用LZW解码
//===========================================================================
DWORD CSckLzw::LZW_Decode (const BYTE *InBuffer, // 输入的数据流
BYTE *OutBuffer) // 解压后的数据
{
LZW_STRING *pString = new LZW_STRING[LZW_MAX_TABLE_SIZE + 32];
if(!pString || !InBuffer || !OutBuffer) return 0;// 字符串表空间
memset(pString, 0xFF, (LZW_MAX_TABLE_SIZE + 32) * sizeof(LZW_STRING));
register WORD i; // 初始化串后缀
for(i=0; i<LZW_CLEAR; i++) pString[i].wSuffix = i;
m_wTableIndex = LZW_END + 1; // 初始化字符表
m_byCurrBits = LZW_MIN_CODE_LEN + 1; // 当前阶段码长
m_pCurrIn = InBuffer; // 原始输入当前
m_pCurrOut = OutBuffer; // 当前指针输出
DWORD dwCurrPixel = 0; // 当前写入点数
BYTE byInBit = 0; // 输入从0开始
WORD wPrefix, wSuffix = LZW_CLEAR, wTemp; // 表索引前后缀
while((wPrefix = Decode_GetNextCode(byInBit)) != LZW_END)
{
if(wPrefix == LZW_CLEAR)
{
memset(pString, 0xFF, (LZW_MAX_TABLE_SIZE + 32) * sizeof(LZW_STRING));
for(i=0; i<LZW_CLEAR; i++) pString[i].wSuffix = i;
m_wTableIndex = LZW_END + 1;
m_byCurrBits = LZW_MIN_CODE_LEN + 1;
while((wPrefix = Decode_GetNextCode(byInBit)) == LZW_CLEAR);
}
else
{
wTemp = (wPrefix < m_wTableIndex) ? wPrefix : wSuffix;
while(pString[wTemp].wPrefix != 0xFFFF) wTemp = pString[wTemp].wPrefix;
pString[m_wTableIndex ].wPrefix = wSuffix;
pString[m_wTableIndex++].wSuffix = pString[wTemp].wSuffix;
if ((m_wTableIndex == 0x008) || (m_wTableIndex == 0x010) ||
(m_wTableIndex == 0x020) || (m_wTableIndex == 0x040) ||
(m_wTableIndex == 0x080) || (m_wTableIndex == 0x100) ||
(m_wTableIndex == 0x200) || (m_wTableIndex == 0x400) ||
(m_wTableIndex == 0x800))
m_byCurrBits++;
}
Decode_WriteStringOut(pString, wPrefix, dwCurrPixel);
wSuffix = wPrefix;
}
delete[] pString; pString = NULL; // 释放字符表
return dwCurrPixel; // 返回原大小
}
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -