www.pudn.com > TOUKUI-1.5.zip > PeeperZip.cpp
///////////////////////////////////////////////////////////////////////////////
// 远程控制软件-偷窥者 压缩库 //
// 日期:2001/10/02 //
// 作者:刘东发 //
// Email:dongfa@yeah.net //
// http://dongfa.yeah.net //
// OICQ:5584173 阿东 //
// 作者声明: //
// 此部分代码是从网上下载获得,经过本人的改写, 变得容易使用,希望能给 //
// 大家带来方便. //
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "PeeperZip.h"
///////////////////////////////////////////////////////////////////////////////
//LZ77 Part START--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
int CCompress::UpperLog2(int n)
{
int i = 0;
if (n > 0)
{
int m = 1;
while(1)
{
if (m >= n)
return i;
m <<= 1;
i++;
}
}
else
return -1;
}
int CCompress::LowerLog2(int n)
{
int i = 0;
if (n > 0)
{
int m = 1;
while(1)
{
if (m == n)
return i;
if (m > n)
return i - 1;
m <<= 1;
i++;
}
}
else
return -1;
}
void CCompress::MovePos(int* piByte, int* piBit, int num)
{
num += (*piBit);
(*piByte) += num / 8;
(*piBit) = num % 8;
}
BYTE CCompress::GetBit(BYTE byte, int pos)
{
int j = 1;
j <<= 7 - pos;
if (byte & j)
return 1;
else
return 0;
}
void CCompress::SetBit(BYTE* byte, int iBit, BYTE aBit)
{
if (aBit)
(*byte) |= (1 << (7 - iBit));
else
(*byte) &= ~(1 << (7 - iBit));
}
void CCompress::InvertDWord(DWORD* pDW)
{
union UDWORD{ DWORD dw; BYTE b[4]; };
UDWORD* pUDW = (UDWORD*)pDW;
BYTE b;
b = pUDW->b[0]; pUDW->b[0] = pUDW->b[3]; pUDW->b[3] = b;
b = pUDW->b[1]; pUDW->b[1] = pUDW->b[2]; pUDW->b[2] = b;
}
void CCompress::CopyBits(BYTE* memDest, int nDestPos,
BYTE* memSrc, int nSrcPos, int nBits)
{
int iByteDest = 0, iBitDest;
int iByteSrc = 0, iBitSrc = nSrcPos;
int nBitsToFill, nBitsCanFill;
while (nBits > 0)
{
nBitsToFill = min(nBits, iByteDest ? 8 : 8 - nDestPos);
iBitDest = iByteDest ? 0 : nDestPos;
nBitsCanFill = min(nBitsToFill, 8 - iBitSrc);
CopyBitsInAByte(memDest + iByteDest, iBitDest,
memSrc + iByteSrc, iBitSrc, nBitsCanFill);
if (nBitsToFill > nBitsCanFill)
{
iByteSrc++; iBitSrc = 0; iBitDest += nBitsCanFill;
CopyBitsInAByte(memDest + iByteDest, iBitDest,
memSrc + iByteSrc, iBitSrc,
nBitsToFill - nBitsCanFill);
iBitSrc += nBitsToFill - nBitsCanFill;
}
else
{
iBitSrc += nBitsCanFill;
if (iBitSrc >= 8)
{
iByteSrc++; iBitSrc = 0;
}
}
nBits -= nBitsToFill;
iByteDest++;
}
}
void CCompress::CopyBitsInAByte(BYTE* memDest, int nDestPos,
BYTE* memSrc, int nSrcPos, int nBits)
{
BYTE b1, b2;
b1 = *memSrc;
b1 <<= nSrcPos; b1 >>= 8 - nBits;
b1 <<= 8 - nBits - nDestPos;
*memDest |= b1;
b2 = 0xff; b2 <<= 8 - nDestPos;
b1 |= b2;
b2 = 0xff; b2 >>= nDestPos + nBits;
b1 |= b2;
*memDest &= b1;
}
CCompressLZ77::CCompressLZ77()
{
SortHeap = new struct STIDXNODE[_MAX_WINDOW_SIZE];
}
CCompressLZ77::~CCompressLZ77()
{
delete[] SortHeap;
}
void CCompressLZ77::_InitSortTable()
{
memset(SortTable, 0, sizeof(WORD) * 65536);
nWndSize = 0;
HeapPos = 1;
}
void CCompressLZ77::_InsertIndexItem(int off)
{
WORD q;
BYTE ch1, ch2;
ch1 = pWnd[off]; ch2 = pWnd[off + 1];
if (ch1 != ch2)
{
q = HeapPos;
HeapPos++;
SortHeap[q].off = off;
SortHeap[q].next = SortTable[ch1 * 256 + ch2];
SortTable[ch1 * 256 + ch2] = q;
}
else
{
q = SortTable[ch1 * 256 + ch2];
if (q != 0 && off == SortHeap[q].off2 + 1)
{
SortHeap[q].off2 = off;
}
else
{
q = HeapPos;
HeapPos++;
SortHeap[q].off = off;
SortHeap[q].off2 = off;
SortHeap[q].next = SortTable[ch1 * 256 + ch2];
SortTable[ch1 * 256 + ch2] = q;
}
}
}
void CCompressLZ77::_ScrollWindow(int n)
{
for (int i = 0; i < n; i++)
{
nWndSize++;
if (nWndSize > 1)
_InsertIndexItem(nWndSize - 2);
}
}
int CCompressLZ77::_GetSameLen(BYTE* src, int srclen, int nSeekStart, int offset)
{
int i = 2;
int maxsame = min(srclen - nSeekStart, nWndSize - offset);
while (i < maxsame
&& src[nSeekStart + i] == pWnd[offset + i])
i++;
_ASSERT(nSeekStart + i <= srclen && offset + i <= nWndSize);
return i;
}
BOOL CCompressLZ77::_SeekPhase(BYTE* src, int srclen, int nSeekStart, int* offset, int* len)
{
int j, m, n;
if (nSeekStart < srclen - 1)
{
BYTE ch1, ch2;
ch1 = src[nSeekStart]; ch2 = src[nSeekStart + 1];
WORD p;
p = SortTable[ch1 * 256 + ch2];
if (p != 0)
{
m = 2; n = SortHeap[p].off;
while (p != 0)
{
j = _GetSameLen(src, srclen,
nSeekStart, SortHeap[p].off);
if ( j > m )
{
m = j;
n = SortHeap[p].off;
}
p = SortHeap[p].next;
}
(*offset) = n;
(*len) = m;
return TRUE;
}
}
return FALSE;
}
void CCompressLZ77::_OutCode(BYTE* dest, DWORD code, int bits, BOOL isGamma)
{
if ( isGamma )
{
BYTE* pb;
DWORD out;
int GammaCode = (int)code - 1;
int q = LowerLog2(GammaCode);
if (q > 0)
{
out = 0xffff;
pb = (BYTE*)&out;
CopyBits(dest + CurByte, CurBit,
pb, 0, q);
MovePos(&CurByte, &CurBit, q);
}
out = 0;
pb = (BYTE*)&out;
CopyBits(dest + CurByte, CurBit, pb + 3, 7, 1);
MovePos(&CurByte, &CurBit, 1);
if (q > 0)
{
int sh = 1;
sh <<= q;
out = GammaCode - sh;
pb = (BYTE*)&out;
InvertDWord(&out);
CopyBits(dest + CurByte, CurBit,
pb + (32 - q) / 8, (32 - q) % 8, q);
MovePos(&CurByte, &CurBit, q);
}
}
else
{
DWORD dw = (DWORD)code;
BYTE* pb = (BYTE*)&dw;
InvertDWord(&dw);
CopyBits(dest + CurByte, CurBit,
pb + (32 - bits) / 8, (32 - bits) % 8, bits);
MovePos(&CurByte, &CurBit, bits);
}
}
int CCompressLZ77::Compress(BYTE* src, int srclen, BYTE* dest)
{
int i;
CurByte = 0; CurBit = 0;
int off, len;
if (srclen > 65536)
return -1;
pWnd = src;
_InitSortTable();
for (i = 0; i < srclen; i++)
{
if (CurByte >= srclen)
return 0;
if (_SeekPhase(src, srclen, i, &off, &len))
{
_OutCode(dest, 1, 1, FALSE);
_OutCode(dest, len, 0, TRUE);
_OutCode(dest, off, UpperLog2(nWndSize), FALSE);
_ScrollWindow(len);
i += len - 1;
}
else
{
_OutCode(dest, 0, 1, FALSE);
_OutCode(dest, (DWORD)(src[i]), 8, FALSE);
_ScrollWindow(1);
}
}
int destlen = CurByte + ((CurBit) ? 1 : 0);
if (destlen >= srclen)
return 0;
return destlen;
}
BOOL CCompressLZ77::Decompress(BYTE* src, int srclen, BYTE* dest)
{
int i;
CurByte = 0; CurBit = 0;
pWnd = src; // 初始化窗口
nWndSize = 0;
if (srclen > 65536)
return FALSE;
for (i = 0; i < srclen; i++)
{
BYTE b = GetBit(dest[CurByte], CurBit);
MovePos(&CurByte, &CurBit, 1);
if (b == 0) // 单个字符
{
CopyBits(src + i, 0, dest + CurByte, CurBit, 8);
MovePos(&CurByte, &CurBit, 8);
nWndSize++;
}
else // 窗口内的术语
{
int q = -1;
while (b != 0)
{
q++;
b = GetBit(dest[CurByte], CurBit);
MovePos(&CurByte, &CurBit, 1);
}
int len, off;
DWORD dw = 0;
BYTE* pb;
if (q > 0)
{
pb = (BYTE*)&dw;
CopyBits(pb + (32 - q) / 8, (32 - q) % 8, dest + CurByte, CurBit, q);
MovePos(&CurByte, &CurBit, q);
InvertDWord(&dw);
len = 1;
len <<= q;
len += dw;
len += 1;
}
else
len = 2;
dw = 0;
pb = (BYTE*)&dw;
int bits = UpperLog2(nWndSize);
CopyBits(pb + (32 - bits) / 8, (32 - bits) % 8, dest + CurByte, CurBit, bits);
MovePos(&CurByte, &CurBit, bits);
InvertDWord(&dw);
off = (int)dw;
for (int j = 0; j < len; j++)
{
_ASSERT(i + j < srclen);
_ASSERT(off + j < _MAX_WINDOW_SIZE);
src[i + j] = pWnd[off + j];
}
nWndSize += len;
i += len - 1;
}
if (nWndSize > _MAX_WINDOW_SIZE)
{
pWnd += nWndSize - _MAX_WINDOW_SIZE;
nWndSize = _MAX_WINDOW_SIZE;
}
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
//LZ77 Part END--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//LZSS Part START--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
HGLOBAL C_LZSS::Encode(char *chData, int nSize)
{
if(!AfxIsValidAddress(chData, nSize))
return NULL;
//缓冲数据区大小
const int nMaxSize = 65536;
HGLOBAL hZip = NULL;
hZip = ::GlobalAlloc(GHND, nMaxSize);
if(hZip == NULL)
{
return NULL;
}
LPBYTE lpZipData = (LPBYTE)::GlobalLock(hZip);
BYTE byMaxBuf[nMaxSize];
ZeroMemory(byMaxBuf, nMaxSize);
int nCurPos = 0; //记下数据的位置
int nZipPos = 0; //记下压缩数据的位置
int nBufPos = 0; //记下当前存储位置hZip
int nZipSize = 0; //压缩后数据的大小
int i, c, len, r, s, last_match_length, code_buf_ptr;
unsigned char code_buf[17], mask;
InitTree();
code_buf[0] = 0;
code_buf_ptr = mask = 1;
s = 0; r = LZSS_N - LZSS_F;
for(i = s; i < r; i++)
{
text_buf[i] = ' ';
}
for(len = 0; len < LZSS_F && (nCurPos < nSize/*getc(infile)*/); len++)
{
c = chData[nCurPos]; //add
nCurPos ++; //add
text_buf[r + len] = c;
}
if((textsize = len) == 0)
{
return false;
}
for(i = 1; i <= LZSS_F; i++)
{
InsertNode(r - i);
}
InsertNode(r);
do
{
if(match_length > len)
{
match_length = len;
}
if(match_length <= LZSS_THRESHOLD)
{
match_length = 1;
code_buf[0] |= mask;
code_buf[code_buf_ptr++] = text_buf[r];
}
else
{
code_buf[code_buf_ptr++] = (unsigned char) match_position;
code_buf[code_buf_ptr++] = (unsigned char)
(((match_position >> 4) & 0xf0)
| (match_length - (LZSS_THRESHOLD + 1)));
}
if((mask <<= 1) == 0)
{
for(i = 0; i < code_buf_ptr; i++)
{
//存储这个压缩字节
if(nZipPos >= nMaxSize)
{
nZipPos = 0;
memcpy(lpZipData + nBufPos, byMaxBuf, nMaxSize);
nBufPos += nMaxSize;
::GlobalUnlock(hZip); //重新分配内存
hZip = ::GlobalReAlloc(hZip, nBufPos + nMaxSize, 0);
lpZipData = (LPBYTE)::GlobalLock(hZip);
}
byMaxBuf[nZipPos] = code_buf[i];
nZipPos ++;
nZipSize ++; //当前压缩数据的大小
}
codesize += code_buf_ptr;
code_buf[0] = 0;
code_buf_ptr = mask = 1;
}
last_match_length = match_length;
for(i = 0; i < last_match_length && (nCurPos < nSize)/*c = getc(infile)) != EOF*/; i++)
{
c = chData[nCurPos]; //add
nCurPos ++; //add
DeleteNode(s);
text_buf[s] = c;
if(s < LZSS_F - 1)
{
text_buf[s + LZSS_N] = c;
}
s = (s + 1) & (LZSS_N - 1);
r = (r + 1) & (LZSS_N - 1);
InsertNode(r);
}
if((textsize += i) > printcount)
{
printcount += 1024;
}
while(i++ < last_match_length)
{
DeleteNode(s);
s = (s + 1) & (LZSS_N - 1);
r = (r + 1) & (LZSS_N - 1);
if(--len)
{
InsertNode(r);
}
}
}while (len > 0);
if(code_buf_ptr > 1)
{
for(i = 0; i < code_buf_ptr; i++)
{
//存储这个压缩字节
if(nZipPos >= nMaxSize)
{
nZipPos = 0;
memcpy(lpZipData + nBufPos, byMaxBuf, nMaxSize);
nBufPos += nMaxSize;
::GlobalUnlock(hZip); //重新分配内存
hZip = ::GlobalReAlloc(hZip, nBufPos + nMaxSize, 0);
lpZipData = (LPBYTE)::GlobalLock(hZip);
}
byMaxBuf[nZipPos] = code_buf[i];
nZipPos ++;
nZipSize ++; //当前压缩数据的大小
}
codesize += code_buf_ptr;
}
//存储剩余的压缩数据
if(nZipPos > 0)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nZipPos);
}
::GlobalUnlock(hZip); //重新分配内存
hZip = ::GlobalReAlloc(hZip, nZipSize, 0);
return hZip;
}
HGLOBAL C_LZSS::Decode(char *chZipData, int nZipSize)
{
if(!AfxIsValidAddress(chZipData, nZipSize))
return NULL;
//缓冲数据区大小
const int nMaxSize = 65536;
HGLOBAL hUnZip = NULL;
hUnZip = ::GlobalAlloc(GHND, nMaxSize);
if(hUnZip == NULL)
{
return NULL;
}
LPBYTE lpUnZipData = (LPBYTE)::GlobalLock(hUnZip);
BYTE byMaxBuf[nMaxSize];
ZeroMemory(byMaxBuf, nMaxSize);
int nCurPos = 0; //记下数据的位置
int nPos = 0; //记下解压数据的位置
int nBufPos = 0; //记下当前存储位置hUnZip
int nSize = 0; //解压后数据的大小
int i, j, k, r, c;
unsigned char cc; //add
unsigned int flags;
for (i = 0; i < LZSS_N - LZSS_F; i++)
{
text_buf[i] = ' ';
}
r = LZSS_N - LZSS_F;
flags = 0;
for( ; ; )
{
if(((flags >>= 1) & 256) == 0)
{
if(nCurPos >= nZipSize)//(c = getc(infile)) == EOF)
{
break;
}
c = (unsigned char)chZipData[nCurPos]; //add
nCurPos ++; //add
flags = c | 0xff00;
}
if(flags & 1)
{
if(nCurPos >= nZipSize)//(c = getc(infile)) == EOF)
{
break;
}
c = (unsigned char)chZipData[nCurPos]; //add
cc = c; //add
nCurPos ++; //add
//存储这个压缩字节
if(nPos >= nMaxSize)
{
nPos = 0;
memcpy(lpUnZipData + nBufPos, byMaxBuf, nMaxSize);
nBufPos += nMaxSize;
::GlobalUnlock(hUnZip); //重新分配内存
hUnZip = ::GlobalReAlloc(hUnZip, nBufPos + nMaxSize, 0);
lpUnZipData = (LPBYTE)::GlobalLock(hUnZip);
}
byMaxBuf[nPos] = cc;
nPos ++;
nSize ++; //当前压缩数据的大小
text_buf[r++] = c;
r &= (LZSS_N - 1);
}
else
{
if(nCurPos >= nZipSize)//(i = getc(infile)) == EOF)
{
break;
}
i = (unsigned char)chZipData[nCurPos]; //add
nCurPos ++; //add
if(nCurPos >= nZipSize)//(j = getc(infile)) == EOF)
{
break;
}
j = chZipData[nCurPos]; //add
nCurPos ++; //add
i |= ((j & 0xf0) << 4);
j = (j & 0x0f) + LZSS_THRESHOLD;
for(k = 0; k <= j; k++)
{
c = text_buf[(i + k) & (LZSS_N - 1)];
cc = c; //add
//存储这个压缩字节
if(nPos >= nMaxSize)
{
nPos = 0;
memcpy(lpUnZipData + nBufPos, byMaxBuf, nMaxSize);
nBufPos += nMaxSize;
::GlobalUnlock(hUnZip); //重新分配内存
hUnZip = ::GlobalReAlloc(hUnZip, nBufPos + nMaxSize, 0);
lpUnZipData = (LPBYTE)::GlobalLock(hUnZip);
}
byMaxBuf[nPos] = cc;
nPos ++;
nSize ++; //当前压缩数据的大小
text_buf[r++] = c;
r &= (LZSS_N - 1);
}
}
}
//存储剩余的解压数据
if(nPos > 0)
{
memcpy(lpUnZipData + nBufPos, byMaxBuf, nPos);
}
::GlobalUnlock(hUnZip); //重新分配内存
hUnZip = ::GlobalReAlloc(hUnZip, nSize, 0);
return hUnZip;
}
///////////////////////////////////////////////////////////////////////////////
//LZSS Part END--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//ARI Part START--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
HGLOBAL C_ARI::Encode(char *chData, int nSize)
{
if(!AfxIsValidAddress(chData, nSize))
return NULL;
if(nSize <= 0)
return NULL;
m_nTotalSize = nSize;
textsize = 0;
codesize = 0;
printcount = 0;
low = 0;
high = ARI_Q4;
value = 0;
shifts = 0;
nCurPos = 0; //记下数据的位置
nZipPos = 0; //记下压缩数据的位置
nBufPos = 0; //记下当前存储位置hZip
nZipSize = 0; //压缩后数据的大小
m_hData = NULL;
m_lpMemData = NULL;
m_lpBuffer = NULL;
m_lpBuffer = (BYTE *)chData;
m_hData = ::GlobalAlloc(GHND, MAXSIZE);
if(m_hData == NULL)
{
return NULL;
}
m_lpMemData = (LPBYTE)::GlobalLock(m_hData);
ZeroMemory(byMaxBuf, MAXSIZE);
nCurPos = 0; //记下数据的位置
nZipPos = 0; //记下压缩数据的位置
nBufPos = 0; //记下当前存储位置hZip
nZipSize = 0; //压缩后数据的大小
int i, c, len, r, s, last_match_length;
textsize = nSize;
int n1 = sizeof(textsize);
memcpy(byMaxBuf, &textsize, sizeof(textsize));
nZipSize += sizeof(textsize);
nZipPos += sizeof(textsize);
/* if(fwrite(&textsize, sizeof textsize, 1, outfile) < 1)
{
Error("Write Error");
}
*/
codesize += sizeof(textsize);
/* if(textsize == 0)
{
return NULL;
}
*/
// rewind(infile);
textsize = 0;
StartModel();
InitTree();
s = 0;
r = ARI_N - ARI_F;
for(i = s; i < r; i++)
{
text_buf[i] = ' ';
}
for(len = 0; len < ARI_F && (nCurPos < nSize)/*c = getc(infile)) != EOF*/; len++)
{
c = m_lpBuffer[nCurPos]; //add
nCurPos ++; //add
text_buf[r + len] = c;
}
textsize = len;
for(i = 1; i <= ARI_F; i++)
{
InsertNode(r - i);
}
InsertNode(r);
do
{
if(match_length > len)
{
match_length = len;
}
if(match_length <= ARI_THRESHOLD)
{
match_length = 1;
EncodeChar(text_buf[r]);
}
else
{
EncodeChar(255 - ARI_THRESHOLD + match_length);
EncodePosition(match_position - 1);
}
last_match_length = match_length;
for(i = 0; i < last_match_length && (nCurPos < nSize)/*c = getc(infile)) != EOF*/; i++)
{
c = m_lpBuffer[nCurPos]; //add
nCurPos ++; //add
DeleteNode(s);
text_buf[s] = c;
if(s < ARI_F - 1)
{
text_buf[s + ARI_N] = c;
}
s = (s + 1) & (ARI_N - 1);
r = (r + 1) & (ARI_N - 1);
InsertNode(r);
}
if((textsize += i) > printcount)
{
printcount += 1024;
}
while(i++ < last_match_length)
{
DeleteNode(s);
s = (s + 1) & (ARI_N - 1);
r = (r + 1) & (ARI_N - 1);
if (--len) InsertNode(r);
}
} while (len > 0);
EncodeEnd();
//存储剩余的压缩数据
if(nZipPos > 0)
{
memcpy(m_lpMemData + nBufPos, byMaxBuf, nZipPos);
}
::GlobalUnlock(m_hData); //重新分配内存
m_hData = ::GlobalReAlloc(m_hData, nZipSize, 0);
return m_hData;
}
HGLOBAL C_ARI::Decode(char *chData, int nSize)
{
if(!AfxIsValidAddress(chData, nSize))
return NULL;
if(nSize <= 4)
return NULL;
m_nTotalSize = nSize;
textsize = 0;
codesize = 0;
printcount = 0;
low = 0;
high = ARI_Q4;
value = 0;
shifts = 0;
nCurPos = 0; //记下数据的位置
nZipPos = 0; //记下压缩数据的位置
nBufPos = 0; //记下当前存储位置hZip
nZipSize = 0; //压缩后数据的大小
m_hData = NULL;
m_lpMemData = NULL;
m_lpBuffer = NULL;
m_lpBuffer = (BYTE *)chData;
m_hData = ::GlobalAlloc(GHND, MAXSIZE);
if(m_hData == NULL)
{
return NULL;
}
m_lpMemData = (LPBYTE)::GlobalLock(m_hData);
ZeroMemory(byMaxBuf, MAXSIZE);
nCurPos = 0; //记下数据的位置
nZipPos = 0; //记下压缩数据的位置
nBufPos = 0; //记下当前存储位置hZip
nZipSize = 0; //压缩后数据的大小
int i, j, k, r, c;
unsigned long int count;
textsize = *(unsigned long int *)(m_lpBuffer);
/* if(fread(&textsize, sizeof textsize, 1, infile) < 1)
{
Error("Read Error");
}
*/
nCurPos += sizeof(textsize);
if(textsize == 0)
{
return NULL;
}
StartDecode();
StartModel();
for(i = 0; i < ARI_N - ARI_F; i++)
{
text_buf[i] = ' ';
}
r = ARI_N - ARI_F;
for(count = 0; count < textsize; )
{
c = DecodeChar();
if(c < 256)
{
//存储这个压缩字节
if(nZipPos >= MAXSIZE)
{
nZipPos = 0;
memcpy(m_lpMemData + nBufPos, byMaxBuf, MAXSIZE);
nBufPos += MAXSIZE;
::GlobalUnlock(m_hData); //重新分配内存
m_hData = ::GlobalReAlloc(m_hData, nBufPos + MAXSIZE, 0);
m_lpMemData = (LPBYTE)::GlobalLock(m_hData);
}
byMaxBuf[nZipPos] = c;
nZipPos ++;
nZipSize ++; //当前压缩数据的大小
text_buf[r++] = c;
r &= (ARI_N - 1);
count++;
}
else
{
i = (r - DecodePosition() - 1) & (ARI_N - 1);
j = c - 255 + ARI_THRESHOLD;
for(k = 0; k < j; k++)
{
c = text_buf[(i + k) & (ARI_N - 1)];
//存储这个压缩字节
if(nZipPos >= MAXSIZE)
{
nZipPos = 0;
memcpy(m_lpMemData + nBufPos, byMaxBuf, MAXSIZE);
nBufPos += MAXSIZE;
::GlobalUnlock(m_hData); //重新分配内存
m_hData = ::GlobalReAlloc(m_hData, nBufPos + MAXSIZE, 0);
m_lpMemData = (LPBYTE)::GlobalLock(m_hData);
}
byMaxBuf[nZipPos] = c;
nZipPos ++;
nZipSize ++; //当前压缩数据的大小
text_buf[r++] = c;
r &= (ARI_N - 1);
count++;
}
}
}
//存储剩余的压缩数据
if(nZipPos > 0)
{
memcpy(m_lpMemData + nBufPos, byMaxBuf, nZipPos);
}
::GlobalUnlock(m_hData); //重新分配内存
m_hData = ::GlobalReAlloc(m_hData, nZipSize, 0);
return m_hData;
}
///////////////////////////////////////////////////////////////////////////////
//ARI Part END--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//LZW Part START--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
CLZWDecodeTable::CLZWDecodeTable(BOOL fInit)
{
m_pbContain=NULL;
m_dwTableEntryNumber=0;
if(fInit)
InitLZWTable();
}
CLZWDecodeTable::~CLZWDecodeTable()
{
ClearDecodeTable();
}
void CLZWDecodeTable::ClearDecodeTable(void)
{
if(m_pbContain==NULL)
return;
for(int i=0;i<4096;i++)
{
if(m_pbContain[i])
delete (m_pbContain[i]);
}
delete m_pbContain;
m_pbContain=NULL;
m_dwTableEntryNumber=0;
}
void CLZWDecodeTable::InitLZWTable(void)
{
ClearDecodeTable();
m_pbContain=new BYTE*[4096];
int iSize=sizeof(m_pbContain);
//if(NULL==m_pbContain)
// AfxMessageBox("error new m_pbContain=BYTE*[4096]");
for(int i=0;i<4096;i++)
{
m_pbContain[i]=NULL;
}
for(i=0;i<=255;i++)
{
m_pbContain[i]=new BYTE[1+2];
*((WORD*)m_pbContain[i])=1;
m_pbContain[i][2]=(BYTE)i;
}
m_dwTableEntryNumber=LZW_BEGIN_ENTRY;
}
BYTE* CLZWDecodeTable::GetMatchData(WORD wCode)
{
return m_pbContain[wCode];
}
void CLZWDecodeTable::AddToChild(WORD wCode,BYTE *pbContain,int iLength)
{
ASSERT(wCode<4096);
if(m_pbContain[wCode])
delete m_pbContain[wCode];
m_pbContain[wCode]=new BYTE[iLength+2];
*((WORD*)m_pbContain[wCode])=(WORD)iLength;
memcpy(m_pbContain[wCode]+2,pbContain,iLength);
}
/*
class CLZWEncodeTable
*/
CLZWEncodeTable::CLZWEncodeTable(BOOL fInit)
{
if(fInit)
InitLZWTable();
else
{
m_dwTableEntryNumber=0;
m_EntryHead.pRightBrother=NULL;
m_EntryHead.pChild=NULL;
}
}
CLZWEncodeTable::~CLZWEncodeTable()
{
ClearLZWTable();
}
void CLZWEncodeTable::ClearLZWTable(void)
{
if(m_EntryHead.pChild==NULL)
return;
m_dwTableEntryNumber=0;
int iRe=0;
while(m_EntryHead.pChild)
{
RemoveFirstChild();
iRe++;
//printf("remove %d\n",++iRe);;
}
}
void CLZWEncodeTable::RemoveFirstChild(void)
{
PLZWENCODEENTRY pFirstChild=m_EntryHead.pChild;// this child will be removed
if(pFirstChild->pChild)
{
m_EntryHead.pChild=pFirstChild->pChild;
if(m_EntryHead.pChild->pRightBrother)
{
PLZWENCODEENTRY pRightBrother=FindRightBrother(m_EntryHead.pChild);
pRightBrother->pRightBrother=pFirstChild->pRightBrother;
}
else
(m_EntryHead.pChild)->pRightBrother=pFirstChild->pRightBrother;
//delete pFirstChild;
}
else
m_EntryHead.pChild=pFirstChild->pRightBrother;
delete pFirstChild;
}
PLZWENCODEENTRY CLZWEncodeTable::FindRightBrother(PLZWENCODEENTRY pCurrent)
{
PLZWENCODEENTRY pFind;
pFind=pCurrent;
while(pFind->pRightBrother)
{
pFind=pFind->pRightBrother;
}
return pFind;
}
void CLZWEncodeTable::InitLZWTable(void)
{// init the table ,it has 256 items code from 0 to 255
ClearLZWTable();
PLZWENCODEENTRY pEntryFirst=new LZWENCODEENTRY;
pEntryFirst->wCode=(WORD)0;
pEntryFirst->bLast=(BYTE)0;
pEntryFirst->pRightBrother=pEntryFirst->pChild=NULL;
m_EntryHead.pChild=pEntryFirst;
m_EntryHead.pRightBrother=NULL;
PLZWENCODEENTRY pPrev=pEntryFirst;
for(int i=1;i<=255;i++)
{// set the brother nodes
PLZWENCODEENTRY pEntry=new LZWENCODEENTRY;
pEntry->wCode=(WORD)i;
pEntry->bLast=(BYTE)i;
pEntry->pChild=pEntry->pRightBrother=NULL;
pPrev->pRightBrother=pEntry;
pPrev=pEntry;
}
m_dwTableEntryNumber=258;
m_uNextCodeForUse=LZW_BEGIN_ENTRY;
}
PLZWENCODEENTRY CLZWEncodeTable::FindMatchChild(BYTE bChildLast,PLZWENCODEENTRY pCurrent)
{// return the find child entry
if(pCurrent->pChild==NULL)
return NULL;
PLZWENCODEENTRY pChild=pCurrent->pChild;
// pChild is the current's child
// and all pChild's brother is the current's child
while(pChild!=NULL)
{
if(pChild->bLast==bChildLast)
return pChild;
pChild=pChild->pRightBrother;
}
return NULL;
}
PLZWENCODEENTRY CLZWEncodeTable::AddToChild(BYTE bLast,PLZWENCODEENTRY pCurrent)
{
ASSERT(pCurrent);
PLZWENCODEENTRY pChild=new LZWENCODEENTRY;
if(pChild==NULL)
{
int _j=0;
}
pChild->pChild=pChild->pRightBrother=NULL;
pChild->bLast=bLast;
pChild->wCode=(WORD)m_uNextCodeForUse;
if(pChild->wCode==LZW_CLEAR_CODE)
{
int _i=0;
}
m_uNextCodeForUse++;
m_dwTableEntryNumber++;
pChild->pRightBrother=pCurrent->pChild;
pCurrent->pChild=pChild;
return pChild;
}
CDecodeBitArray::CDecodeBitArray(DWORD dwInitWidth)// width in bit
{
m_pbBits=NULL;
m_dwWidthInByte=0;
m_dwTail=m_dwHead=0;
if(dwInitWidth)
InitBits(dwInitWidth);
}
CDecodeBitArray::~CDecodeBitArray()
{
ClearBits();
}
void CDecodeBitArray::ClearBits(void)
{
if(m_pbBits)
delete m_pbBits;
m_dwTail=m_dwHead=0;
m_dwWidthInByte=0;
}
void CDecodeBitArray::InitBits(DWORD dwInitWidth)
{
ClearBits();
DWORD dwLength=dwInitWidth/8;
dwLength+=(dwInitWidth%8)?1:0;
m_pbBits=new BYTE[dwLength];
m_dwHead=m_dwTail=0;
m_dwWidthInByte=dwLength;
}
void CDecodeBitArray::InitBytes(DWORD dwInitWidth)
{
InitBits(dwInitWidth*8);
}
DWORD CDecodeBitArray::GetLeftBytes(void)
{
DWORD dwLeftBytes;
DWORD dwLeftBits=GetLeftBits();
dwLeftBytes=dwLeftBits/8;
dwLeftBytes+=(dwLeftBits%8)?1:0;
return dwLeftBytes;
}
WORD CDecodeBitArray::RemoveBits(int iWidth)
{
WORD wGet=0;
for(int i=iWidth-1;i>=0;i--)
{
if(RemoveFirstBit())
{
(wGet |= (1<=0;i--)
{
BYTE* pbByte=m_pbBits+m_dwTail/8;
if((wAdd & (1<iTotal)
iWant=iTotal;
if(pbGet!=NULL)
memcpy(pbGet,m_pbBits,iWant);
memcpy(m_pbBits,m_pbBits+iWant,iTotal-iWant);
int iTail=(int)m_dwTail;
iTail-=iWant*8;
if(iTail<0)
iTail=0;
m_dwTail=iTail;
return iWant;
}
HGLOBAL CLZWDecode::BeginLZWDecode(char *chZipData, int dwLength)
{
if(!AfxIsValidAddress(chZipData, dwLength))
return NULL;
//缓冲数据区大小
const int nMaxSize = 65536;
HGLOBAL hUnZip = NULL;
hUnZip = ::GlobalAlloc(GHND, nMaxSize);
if(hUnZip == NULL)
{
return NULL;
}
LPBYTE lpZipData = (LPBYTE)::GlobalLock(hUnZip);
BYTE byMaxBuf[nMaxSize];
ZeroMemory(byMaxBuf, nMaxSize);
int nZipPos = 0; //记下压缩数据的位置
int nBufPos = 0; //记下当前存储位置hZip
int nZipSize = 0; //压缩后数据的大小
iDePutPos=iDeGetPos=0;
DWORD dwBytesOnce = 1;
DWORD wBuffer = 1024;
m_dwDecodedByte=0;
BYTE *pbNewData=new BYTE[4000],*pbOutData=new BYTE[4000];
BYTE *pbBuffer=new BYTE[wBuffer];
BYTE bFirst;
m_LZWTable.InitLZWTable();
int iBitWidth=9;
m_iTotalEntry=LZW_BEGIN_ENTRY;
BYTE* pbDecodedData;
WORD wOld,wLastLen;
m_baContain.InitBits((wBuffer+20)*8);
int iR=0;
DWORD dwRead=0;
while(1)
{
if(m_baContain.GetLeftBytes()<5)
{
WORD wGetBytes= (WORD)wBuffer;
if((DWORD)wGetBytes+dwRead>(DWORD)dwLength)
wGetBytes=(WORD)(dwLength-dwRead);
if(wGetBytes!=0)
{
///////////////////////////////////
int iGet = wGetBytes;
if(iDeGetPos + iGet > dwLength)
iGet = dwLength - iDeGetPos;
memcpy(pbBuffer, chZipData + iDeGetPos, iGet);
iDeGetPos += iGet;
///////////////////////////////////
m_baContain.AddBytes(pbBuffer,wBuffer);
dwRead+=wGetBytes;
}
}
int iT=m_iTotalEntry+1;
iT>>=9;
iBitWidth=9;
while(iT>0)
{
iT>>=1;
iBitWidth++;
}
WORD wGet=m_baContain.RemoveBits(iBitWidth);
if(wGet==LZW_END_CODE)
{
break;
}
if(wGet==LZW_CLEAR_CODE)
{
m_LZWTable.InitLZWTable();
wGet=m_baContain.RemoveBits(9);
if(wGet==LZW_END_CODE)
break;
pbDecodedData=m_LZWTable.GetMatchData(wGet);
//////////////////////////////
BYTE *pbWrite = pbDecodedData;
if(pbWrite != NULL)
{
WORD wL=*((WORD*)pbWrite);
pbWrite+=sizeof(WORD);
for(DWORD i=0;i= nMaxSize)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nMaxSize);
nBufPos += nMaxSize;
nZipPos = 0;
::GlobalUnlock(hUnZip); //重新分配内存
hUnZip = ::GlobalReAlloc(hUnZip, nBufPos + nMaxSize, 0);
lpZipData = (LPBYTE)::GlobalLock(hUnZip);
}
byMaxBuf[nZipPos] = *pbWrite;
nZipPos ++;//
nZipSize ++; //add
pbWrite++;
}
m_dwDecodedByte+=wL;
}
//////////////////////////////
wOld=wGet;
m_iTotalEntry=258;
}
else
{// not clear
pbDecodedData=m_LZWTable.GetMatchData(wGet);
if(NULL!=pbDecodedData)
{// in table
bFirst=pbDecodedData[2];
//////////////////////////////
BYTE *pbWrite = pbDecodedData;
if(pbWrite != NULL)
{
WORD wL=*((WORD*)pbWrite);
pbWrite+=sizeof(WORD);
for(DWORD i=0;i= nMaxSize)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nMaxSize);
nBufPos += nMaxSize;
nZipPos = 0;
::GlobalUnlock(hUnZip); //重新分配内存
hUnZip = ::GlobalReAlloc(hUnZip, nBufPos + nMaxSize, 0);
lpZipData = (LPBYTE)::GlobalLock(hUnZip);
}
byMaxBuf[nZipPos] = *pbWrite;
nZipPos ++;//
nZipSize ++; //add
pbWrite++;
}
m_dwDecodedByte+=wL;
}
//////////////////////////////
if(wOld!=LZW_CLEAR_CODE)
{// not the first code be read in
pbDecodedData=m_LZWTable.GetMatchData(wOld);
wLastLen=*((WORD*)pbDecodedData);
memcpy(pbNewData,pbDecodedData+2,wLastLen);
pbNewData[wLastLen]=bFirst;
m_LZWTable.AddToChild((WORD)m_iTotalEntry,pbNewData,wLastLen+1);
m_iTotalEntry+=1;
}
wOld=wGet;
}
else
{
pbDecodedData=m_LZWTable.GetMatchData(wOld);
bFirst=pbDecodedData[2];
wLastLen=*((WORD*)pbDecodedData);
memcpy(pbOutData+2,pbDecodedData+2,wLastLen);
pbOutData[wLastLen+2]=bFirst;
*((WORD*)pbOutData)=wLastLen+1;
//////////////////////////////
BYTE *pbWrite = pbOutData;
if(pbWrite != NULL)
{
WORD wL=*((WORD*)pbWrite);
pbWrite+=sizeof(WORD);
for(DWORD i=0;i= nMaxSize)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nMaxSize);
nBufPos += nMaxSize;
nZipPos = 0;
::GlobalUnlock(hUnZip); //重新分配内存
hUnZip = ::GlobalReAlloc(hUnZip, nBufPos + nMaxSize, 0);
lpZipData = (LPBYTE)::GlobalLock(hUnZip);
}
byMaxBuf[nZipPos] = *pbWrite;
nZipPos ++;//
nZipSize ++; //add
pbWrite++;
}
m_dwDecodedByte+=wL;
}
//////////////////////////////
if(m_iTotalEntry>=4096)
{
int _j=0;
}
m_LZWTable.AddToChild((WORD)m_iTotalEntry,pbOutData+2,wLastLen+1);
m_iTotalEntry+=1;
wOld=wGet;
}
}
}
delete pbNewData;
delete pbOutData;
delete pbBuffer;
if(dwRead != (DWORD)dwLength)
{
GlobalFree(hUnZip);
hUnZip = NULL;
}
//存储剩余的压缩数据
if(nZipPos > 0)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nZipPos);
}
::GlobalUnlock(hUnZip); //重新分配内存
hUnZip = ::GlobalReAlloc(hUnZip, nZipSize, 0);
return hUnZip;
}
/*
CLZWEncode
*/
HGLOBAL CLZWEncode::BeginLZWEncode(char *chData, int dwLength)
{
if(!AfxIsValidAddress(chData, dwLength))
return NULL;
//缓冲数据区大小
const int nMaxSize = 65536;
HGLOBAL hZip = NULL;
hZip = ::GlobalAlloc(GHND, nMaxSize);
if(hZip == NULL)
{
return NULL;
}
LPBYTE lpZipData = (LPBYTE)::GlobalLock(hZip);
BYTE byMaxBuf[nMaxSize];
ZeroMemory(byMaxBuf, nMaxSize);
int nZipPos = 0; //记下压缩数据的位置
int nBufPos = 0; //记下当前存储位置hZip
int nZipSize = 0; //压缩后数据的大小
m_dwCompressedLength = 0;
WORD wBufferLen = 1024;
int iBufferLen = wBufferLen = 1024;
BYTE bGet;
int nCurPos = 0;
m_LZWTable.InitLZWTable();// init the entry table
m_baContain.InitBits((iBufferLen+8)*8);// init the bit array
m_baContain.AddBits(LZW_CLEAR_CODE,9);// add the first clear code
/// below : begin the algorithm
PLZWENCODEENTRY pCurrent = m_LZWTable.GetHead();
int iBitWidth;
DWORD dwEncoded=0;
for(DWORD i = 0; i < (DWORD)dwLength; i ++)
{// for each byte
bGet = chData[nCurPos]; // add
nCurPos ++;
PLZWENCODEENTRY pChild=m_LZWTable.FindMatchChild(bGet,pCurrent);
if(pChild)
{// has found the continue
pCurrent=pChild;
}
else
{// not find write last code & add new entry
iBitWidth=GetBitWidth();
WORD wW=pCurrent->wCode;
m_baContain.AddBits(wW,iBitWidth);// add last code to buffer
m_LZWTable.AddToChild(bGet,pCurrent);// add last code to table
if(m_baContain.GetBytesWidth()>(DWORD)iBufferLen)
{
m_dwCompressedLength+=(DWORD)iBufferLen;
//存储这个压缩
if(nZipPos + iBufferLen >= nMaxSize)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nZipPos);
nBufPos += nZipPos;
nZipPos = 0;
::GlobalUnlock(hZip); //重新分配内存
hZip = ::GlobalReAlloc(hZip, nBufPos + nMaxSize, 0);
lpZipData = (LPBYTE)::GlobalLock(hZip);
}
memcpy(byMaxBuf + nZipPos, m_baContain.GetBits(), iBufferLen);
nZipPos += iBufferLen;
nZipSize += iBufferLen; //add
m_baContain.RemoveBytes(NULL,iBufferLen);
}
if(m_LZWTable.GetTableEntryNumber()>= (DWORD)(m_wMaxEntry-3))
{
iBitWidth=GetBitWidth();
m_baContain.AddBits(LZW_CLEAR_CODE,iBitWidth);
m_LZWTable.InitLZWTable();
}
pCurrent=m_LZWTable.FindMatchChild(bGet,m_LZWTable.GetHead());
}
dwEncoded++;
}
iBitWidth=GetBitWidth();
m_baContain.AddBits(pCurrent->wCode,iBitWidth);// add last code to buffer
iBitWidth=GetBitWidth();
m_baContain.AddBits(LZW_END_CODE,iBitWidth);
m_dwCompressedLength+=m_baContain.GetBytesWidth();
iBufferLen = m_baContain.GetBytesWidth();
//存储这个压缩
if(nZipPos + iBufferLen >= nMaxSize)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nZipPos);
nBufPos += nZipPos;
nZipPos = 0;
::GlobalUnlock(hZip); //重新分配内存
hZip = ::GlobalReAlloc(hZip, nBufPos + nMaxSize, 0);
lpZipData = (LPBYTE)::GlobalLock(hZip);
}
memcpy(byMaxBuf + nZipPos, m_baContain.GetBits(), iBufferLen);
nZipPos += iBufferLen;
nZipSize += iBufferLen; //add
m_LZWTable.ClearLZWTable();
m_baContain.ClearBits();
//存储剩余的压缩数据
if(nZipPos > 0)
{
memcpy(lpZipData + nBufPos, byMaxBuf, nZipPos);
}
::GlobalUnlock(hZip); //重新分配内存
hZip = ::GlobalReAlloc(hZip, nZipSize, 0);
return hZip;
}
int CLZWEncode::GetBitWidth(void)
{
int iTotal=(int)m_LZWTable.GetTableEntryNumber();
iTotal>>=9;
int iBitWidth=9;
while(iTotal>0)
{
iTotal>>=1;
iBitWidth+=1;
}
return iBitWidth;
}
HGLOBAL C_LZW::Encode(char *chData, int nSize)
{
CLZWEncode cl;
return cl.BeginLZWEncode(chData, nSize);
}
HGLOBAL C_LZW::Decode(char *chZipData, int nZipSize)
{
CLZWDecode cl;
return cl.BeginLZWDecode(chZipData, nZipSize);
}
///////////////////////////////////////////////////////////////////////////////
//LZW Part END--------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////