?? 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 + -