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-------------------------------------------------------------- 
///////////////////////////////////////////////////////////////////////////////