www.pudn.com > 大型远程控制软件(偷窥者)源码大公开.zip > PeeperZip.h


/////////////////////////////////////////////////////////////////////////////// 
// 远程控制软件-偷窥者  压缩库                                               // 
// 日期:2001/10/02                                                           // 
// 作者:刘东发                                                               // 
// Email:dongfa@yeah.net                                                     // 
// http://dongfa.yeah.net                                                    // 
// OICQ:5584173  阿东                                                        // 
// 作者声明:                                                                 // 
//     此部分代码是从网上下载获得,经过本人的改写, 变得容易使用,希望能给   // 
// 大家带来方便.                                                             // 
/////////////////////////////////////////////////////////////////////////////// 
 
#ifndef __PEEPER_ZIP_H__ 
#define __PEEPER_ZIP_H__ 
 
 
/////////////////////////////////////////////////////////////////////////////// 
//LZ77 Part START-------------------------------------------------------------- 
/////////////////////////////////////////////////////////////////////////////// 
#define _MAX_WINDOW_SIZE	65536 
class CCompress 
{ 
public: 
	CCompress() {}; 
	virtual ~CCompress() {}; 
 
public: 
	virtual int Compress(BYTE* src, int srclen, BYTE* dest) = 0; 
	virtual BOOL Decompress(BYTE* src, int srclen, BYTE* dest) = 0; 
 
protected: 
	void CopyBitsInAByte(BYTE* memDest, int nDestPos,  
				  BYTE* memSrc, int nSrcPos, int nBits); 
	void CopyBits(BYTE* memDest, int nDestPos,  
				  BYTE* memSrc, int nSrcPos, int nBits); 
 
	void InvertDWord(DWORD* pDW); 
	void SetBit(BYTE* byte, int iBit, BYTE aBit); 
	BYTE GetBit(BYTE byte, int pos); 
	void MovePos(int* piByte, int* piBit, int num); 
	int UpperLog2(int n); 
	int LowerLog2(int n); 
}; 
 
class CCompressLZ77 : public CCompress 
{ 
public: 
	CCompressLZ77(); 
	virtual ~CCompressLZ77(); 
public: 
	int Compress(BYTE* src, int srclen, BYTE* dest); 
	BOOL Decompress(BYTE* src, int srclen, BYTE* dest); 
 
protected: 
	BYTE* pWnd; 
	int nWndSize; 
	struct STIDXNODE 
	{ 
		WORD off; 
		WORD off2; 
		WORD next; 
	}; 
	WORD SortTable[65536]; 
	struct STIDXNODE* SortHeap; 
	int HeapPos; 
	int CurByte, CurBit; 
protected: 
	void _OutCode(BYTE* dest, DWORD code, int bits, BOOL isGamma); 
	BOOL _SeekPhase(BYTE* src, int srclen, int nSeekStart, int* offset, int* len); 
	inline int _GetSameLen(BYTE* src, int srclen, int nSeekStart, int offset); 
	inline void _ScrollWindow(int n); 
	inline void _InsertIndexItem(int off); 
	void _InitSortTable(); 
}; 
/////////////////////////////////////////////////////////////////////////////// 
//LZ77 Part END-------------------------------------------------------------- 
/////////////////////////////////////////////////////////////////////////////// 
 
 
 
/////////////////////////////////////////////////////////////////////////////// 
//LZSS Part START-------------------------------------------------------------- 
/////////////////////////////////////////////////////////////////////////////// 
#define LZSS_N			4096 
#define LZSS_F			18 
#define LZSS_THRESHOLD	2 
#define LZSS_NIL		LZSS_N 
 
class C_LZSS 
{ 
public: 
	C_LZSS() 
	{ 
		textsize = 0; 
		codesize = 0; 
		printcount = 0; 
	} 
	~C_LZSS() 
	{ 
	} 
 
	HGLOBAL Encode(char *chData, int nSize); 
	HGLOBAL Decode(char *chZipData, int nZipSize); 
 
protected: 
	void InitTree(void) 
	{ 
		int i = 0; 
		for(i = LZSS_N + 1; i <= LZSS_N + 256; i++) 
		{ 
			rson[i] = LZSS_NIL; 
		} 
		for(i = 0; i < LZSS_N; i++) 
		{ 
			dad[i] = LZSS_NIL; 
		} 
	} 
 
	void InsertNode(int r) 
	{ 
		int i = 0; 
		int p = 0; 
		int cmp = 1; 
		unsigned char *key = &text_buf[r]; 
		p = LZSS_N + 1 + key[0]; 
		rson[r] = lson[r] = LZSS_NIL; 
		match_length = 0; 
		for( ; ; ) 
		{ 
			if(cmp >= 0) 
			{ 
				if(rson[p] != LZSS_NIL) 
				{ 
					p = rson[p]; 
				} 
				else 
				{ 
					rson[p] = r; 
					dad[r] = p; 
					return ; 
				} 
			} 
			else 
			{ 
				if(lson[p] != LZSS_NIL) 
				{ 
					p = lson[p]; 
				} 
				else 
				{ 
					lson[p] = r; 
					dad[r] = p; 
					return ; 
				} 
			} 
			for(i = 1; i < LZSS_F; i++) 
			{ 
				if ((cmp = key[i] - text_buf[p + i]) != 0) 
					break; 
			} 
			if(i > match_length) 
			{ 
				match_position = p; 
				if((match_length = i) >= LZSS_F) 
					break; 
			} 
		} 
		dad[r] = dad[p]; 
		lson[r] = lson[p]; 
		rson[r] = rson[p]; 
		dad[lson[p]] = r; 
		dad[rson[p]] = r; 
		if(rson[dad[p]] == p) 
		{ 
			rson[dad[p]] = r; 
		} 
		else 
		{ 
			lson[dad[p]] = r; 
		} 
		dad[p] = LZSS_NIL; 
	} 
	 
	void DeleteNode(int p) 
	{ 
		int q = 0; 
		if(dad[p] == LZSS_NIL) 
			return ; 
		if(rson[p] == LZSS_NIL) 
		{ 
			q = lson[p]; 
		} 
		else if(lson[p] == LZSS_NIL) 
		{ 
			q = rson[p]; 
		} 
		else 
		{ 
			q = lson[p]; 
			if(rson[q] != LZSS_NIL) 
			{ 
				do 
				{ 
					q = rson[q]; 
				}while (rson[q] != LZSS_NIL); 
				rson[dad[q]] = lson[q]; 
				dad[lson[q]] = dad[q]; 
				lson[q] = lson[p]; 
				dad[lson[p]] = q; 
			} 
			rson[q] = rson[p]; 
			dad[rson[p]] = q; 
		} 
		dad[q] = dad[p]; 
		if(rson[dad[p]] == p) 
		{ 
			rson[dad[p]] = q; 
		} 
		else 
		{ 
			lson[dad[p]] = q; 
		} 
		dad[p] = LZSS_NIL; 
	} 
	 
protected: 
	unsigned long int textsize; 
	unsigned long int codesize; 
	unsigned long int printcount; 
	unsigned char text_buf[LZSS_N + LZSS_F - 1]; 
	int match_position; 
	int match_length; 
	int lson[LZSS_N + 1]; 
	int rson[LZSS_N + 257]; 
	int dad[LZSS_N + 1]; 
//	FILE *infile; 
//	FILE *outfile; 
}; 
 
/////////////////////////////////////////////////////////////////////////////// 
//LZSS Part END-------------------------------------------------------------- 
/////////////////////////////////////////////////////////////////////////////// 
 
 
/////////////////////////////////////////////////////////////////////////////// 
//ARI Part START-------------------------------------------------------------- 
/////////////////////////////////////////////////////////////////////////////// 
#define ARI_N			4096 
#define ARI_F			60 
#define ARI_THRESHOLD	2 
#define ARI_NIL			ARI_N 
#define ARI_M   15 
#define ARI_Q1  (1UL << ARI_M) 
#define ARI_Q2  (2 * ARI_Q1) 
#define ARI_Q3  (3 * ARI_Q1) 
#define ARI_Q4  (4 * ARI_Q1) 
#define ARI_MAX_CUM (ARI_Q1 - 1) 
#define ARI_N_CHAR  (256 - ARI_THRESHOLD + ARI_F) 
 
//缓冲数据区大小 
const int MAXSIZE = 65536; 
 
class C_ARI 
{ 
public: 
	C_ARI() 
	{ 
		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_nTotalSize = 0; 
 
		m_hData = NULL; 
		m_lpMemData = NULL; 
		m_lpBuffer = NULL; 
	} 
	~C_ARI() 
	{ 
	} 
 
	HGLOBAL Encode(char *chData, int nSize); 
	HGLOBAL Decode(char *chZipData, int nZipSize); 
 
protected: 
	void Error(char *message) 
	{ 
		printf("\n%s\n", message); 
		exit(EXIT_FAILURE); 
	} 
 
	void PutBit(int bit) 
	{ 
		static unsigned int buffer = 0, mask = 128; 
		if(bit) 
		{ 
			buffer |= mask; 
		} 
		if((mask >>= 1) == 0) 
		{ 
			//存储这个压缩字节 
			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] = buffer; 
			nZipPos ++; 
			nZipSize ++; //当前压缩数据的大小 
 
			buffer = 0; 
			mask = 128; 
			codesize++; 
		} 
	} 
	 
	void FlushBitBuffer(void) 
	{ 
		for(int i = 0; i < 7; i ++) 
		{ 
			PutBit(0); 
		} 
	} 
	 
	int GetBit(void) 
	{ 
		static unsigned int buffer, mask = 0; 
		if((mask >>= 1) == 0) 
		{ 
			if(nCurPos < m_nTotalSize) 
			{ 
				buffer = m_lpBuffer[nCurPos]; //add 
				nCurPos ++; //add 
			} 
			mask = 128; 
		} 
		return ((buffer & mask) != 0); 
	} 
	 
	void InitTree(void) 
	{ 
		int i = 0; 
		for(i = ARI_N + 1; i <= ARI_N + 256; i++) 
		{ 
			rson[i] = ARI_NIL; 
		} 
		for(i = 0; i < ARI_N; i++) 
		{ 
			dad[i] = ARI_NIL; 
		} 
	} 
	 
	void InsertNode(int r) 
	{ 
		int i, p, cmp, temp; 
		unsigned char *key; 
		cmp = 1; 
		key = &text_buf[r]; 
		p = ARI_N + 1 + key[0]; 
		rson[r] = lson[r] = ARI_NIL; 
		match_length = 0; 
		for( ; ; ) 
		{ 
			if(cmp >= 0) 
			{ 
				if(rson[p] != ARI_NIL) 
				{ 
					p = rson[p]; 
				} 
				else 
				{ 
					rson[p] = r; 
					dad[r] = p; 
					return; 
				} 
			} 
			else 
			{ 
				if(lson[p] != ARI_NIL) 
				{ 
					p = lson[p]; 
				} 
				else 
				{ 
					lson[p] = r; 
					dad[r] = p; 
					return ; 
				} 
			} 
			for(i = 1; i < ARI_F; i ++) 
			{ 
				if((cmp = key[i] - text_buf[p + i]) != 0) 
					break; 
			} 
			if(i > ARI_THRESHOLD) 
			{ 
				if (i > match_length) 
				{ 
					match_position = (r - p) & (ARI_N - 1); 
					if((match_length = i) >= ARI_F) 
					{ 
						break; 
					} 
				} 
				else if (i == match_length) 
				{ 
					if ((temp = (r - p) & (ARI_N - 1)) < match_position) 
						match_position = temp; 
				} 
			} 
		} 
		dad[r] = dad[p]; 
		lson[r] = lson[p]; 
		rson[r] = rson[p]; 
		dad[lson[p]] = r; 
		dad[rson[p]] = r; 
		if(rson[dad[p]] == p) 
		{ 
			rson[dad[p]] = r; 
		} 
		else 
		{ 
			lson[dad[p]] = r; 
		} 
		dad[p] = ARI_NIL; 
	} 
	 
	void DeleteNode(int p) 
	{ 
		int q = 0; 
		if(dad[p] == ARI_NIL) 
		{ 
			return ; 
		} 
		if(rson[p] == ARI_NIL) 
		{ 
			q = lson[p]; 
		} 
		else if(lson[p] == ARI_NIL) 
		{ 
			q = rson[p]; 
		} 
		else 
		{ 
			q = lson[p]; 
			if(rson[q] != ARI_NIL) 
			{ 
				do 
				{ 
					q = rson[q]; 
				}while (rson[q] != ARI_NIL); 
				rson[dad[q]] = lson[q]; 
				dad[lson[q]] = dad[q]; 
				lson[q] = lson[p]; 
				dad[lson[p]] = q; 
			} 
			rson[q] = rson[p]; 
			dad[rson[p]] = q; 
		} 
		dad[q] = dad[p]; 
		if(rson[dad[p]] == p) 
		{ 
			rson[dad[p]] = q; 
		} 
		else 
		{ 
			lson[dad[p]] = q; 
		} 
		dad[p] = ARI_NIL; 
	} 
	 
	void StartModel(void) 
	{ 
		int ch, sym, i; 
		sym_cum[ARI_N_CHAR] = 0; 
		for(sym = ARI_N_CHAR; sym >= 1; sym --) 
		{ 
			ch = sym - 1; 
			char_to_sym[ch] = sym; 
			sym_to_char[sym] = ch; 
			sym_freq[sym] = 1; 
			sym_cum[sym - 1] = sym_cum[sym] + sym_freq[sym]; 
		} 
		sym_freq[0] = 0; 
		position_cum[ARI_N] = 0; 
		for(i = ARI_N; i >= 1; i--) 
		{ 
			position_cum[i - 1] = position_cum[i] + 10000 / (i + 200); 
		} 
	} 
	 
	void UpdateModel(int sym) 
	{ 
		int i, c, ch_i, ch_sym; 
		if(sym_cum[0] >= ARI_MAX_CUM) 
		{ 
			c = 0; 
			for(i = ARI_N_CHAR; i > 0; i--) 
			{ 
				sym_cum[i] = c; 
				c += (sym_freq[i] = (sym_freq[i] + 1) >> 1); 
			} 
			sym_cum[0] = c; 
		} 
		for(i = sym; sym_freq[i] == sym_freq[i - 1]; i--); 
		if(i < sym) 
		{ 
			ch_i = sym_to_char[i]; 
			ch_sym = sym_to_char[sym]; 
			sym_to_char[i] = ch_sym; 
			sym_to_char[sym] = ch_i; 
			char_to_sym[ch_i] = sym; 
			char_to_sym[ch_sym] = i; 
		} 
		sym_freq[i]++; 
		while(--i >= 0) 
		{ 
			sym_cum[i] ++; 
		} 
	} 
	 
	void Output(int bit) 
	{ 
		PutBit(bit); 
		for( ; shifts > 0; shifts--) 
		{ 
			PutBit(! bit); 
		} 
	} 
	 
	void EncodeChar(int ch) 
	{ 
		int  sym; 
		unsigned long int  range; 
		sym = char_to_sym[ch]; 
		range = high - low; 
		high = low + (range * sym_cum[sym - 1]) / sym_cum[0]; 
		low += (range * sym_cum[sym]) / sym_cum[0]; 
		for( ; ; ) 
		{ 
			if(high <= ARI_Q2) 
			{ 
				Output(0); 
			} 
			else if(low >= ARI_Q2) 
			{ 
				Output(1); 
				low -= ARI_Q2; 
				high -= ARI_Q2; 
			} 
			else if(low >= ARI_Q1 && high <= ARI_Q3) 
			{ 
				shifts ++; 
				low -= ARI_Q1; 
				high -= ARI_Q1; 
			} 
			else 
			{ 
				break; 
			} 
			low += low; 
			high += high; 
		} 
		UpdateModel(sym); 
	} 
	 
	void EncodePosition(int position) 
	{ 
		unsigned long int range; 
		range = high - low; 
		high = low + (range * position_cum[position]) / position_cum[0]; 
		low += (range * position_cum[position + 1]) / position_cum[0]; 
		for( ; ; ) 
		{ 
			if (high <= ARI_Q2) 
			{ 
				Output(0); 
			} 
			else if(low >= ARI_Q2) 
			{ 
				Output(1); 
				low -= ARI_Q2; 
				high -= ARI_Q2; 
			} 
			else if(low >= ARI_Q1 && high <= ARI_Q3) 
			{ 
				shifts++; 
				low -= ARI_Q1; 
				high -= ARI_Q1; 
			} 
			else 
			{ 
				break; 
			} 
			low += low; 
			high += high; 
		} 
	} 
	 
	void EncodeEnd(void) 
	{ 
		shifts++; 
		if(low < ARI_Q1) 
		{ 
			Output(0); 
		} 
		else 
		{ 
			Output(1); 
		} 
		FlushBitBuffer(); 
	} 
	 
	int BinarySearchSym(unsigned int x) 
	{ 
		int i, j, k; 
		i = 1; 
		j = ARI_N_CHAR; 
		while(i < j) 
		{ 
			k = (i + j) / 2; 
			if(sym_cum[k] > x) 
			{ 
				i = k + 1; 
			} 
			else 
			{ 
				j = k; 
			} 
		} 
		return i; 
	} 
	 
	int BinarySearchPos(unsigned int x) 
	{ 
		int i, j, k; 
		i = 1;  j = ARI_N; 
		while(i < j) 
		{ 
			k = (i + j) / 2; 
			if(position_cum[k] > x) 
			{ 
				i = k + 1; 
			} 
			else 
			{ 
				j = k; 
			} 
		} 
		return i - 1; 
	} 
	 
	void StartDecode(void) 
	{ 
		int i; 
		for(i = 0; i < ARI_M + 2; i++) 
		{ 
			value = 2 * value + GetBit(); 
		} 
	} 
	 
	int DecodeChar(void) 
	{ 
		int	 sym, ch; 
		unsigned long int  range; 
		range = high - low; 
		sym = BinarySearchSym((unsigned int)(((value - low + 1) * sym_cum[0] - 1) / range)); 
		high = low + (range * sym_cum[sym - 1]) / sym_cum[0]; 
		low += (range * sym_cum[sym]) / sym_cum[0]; 
		for( ; ; ) 
		{ 
			if(low >= ARI_Q2) 
			{ 
				value -= ARI_Q2; 
				low -= ARI_Q2; 
				high -= ARI_Q2; 
			} 
			else if(low >= ARI_Q1 && high <= ARI_Q3) 
			{ 
				value -= ARI_Q1; 
				low -= ARI_Q1; 
				high -= ARI_Q1; 
			} 
			else if (high > ARI_Q2) 
			{ 
				break; 
			} 
			low += low; 
			high += high; 
			value = 2 * value + GetBit(); 
		} 
		ch = sym_to_char[sym]; 
		UpdateModel(sym); 
		return ch; 
	} 
	 
	int DecodePosition(void) 
	{ 
		int position; 
		unsigned long int  range; 
		range = high - low; 
		position = BinarySearchPos((unsigned int)(((value - low + 1) * position_cum[0] - 1) / range)); 
		high = low + (range * position_cum[position]) / position_cum[0]; 
		low += (range * position_cum[position + 1]) / position_cum[0]; 
		for( ; ; ) 
		{ 
			if(low >= ARI_Q2) 
			{ 
				value -= ARI_Q2; 
				low -= ARI_Q2; 
				high -= ARI_Q2; 
			} 
			else if(low >= ARI_Q1 && high <= ARI_Q3) 
			{ 
				value -= ARI_Q1; 
				low -= ARI_Q1; 
				high -= ARI_Q1; 
			} 
			else if(high > ARI_Q2) 
			{ 
				break; 
			} 
			low += low; 
			high += high; 
			value = 2 * value + GetBit(); 
		} 
		return position; 
	} 
	 
 
protected: 
	unsigned long int textsize; 
	unsigned long int codesize; 
	unsigned long int printcount; 
 
	unsigned char text_buf[ARI_N + ARI_F - 1]; 
	int match_position; 
	int match_length; 
	int lson[ARI_N + 1]; 
	int rson[ARI_N + 257]; 
	int dad[ARI_N + 1]; 
 
	 
	unsigned long int low; 
	unsigned long int high; 
	unsigned long int value; 
	int shifts; 
	int char_to_sym[ARI_N_CHAR]; 
	int sym_to_char[ARI_N_CHAR + 1]; 
	unsigned int sym_freq[ARI_N_CHAR + 1]; 
	unsigned int sym_cum[ARI_N_CHAR + 1]; 
	unsigned int position_cum[ARI_N + 1]; 
	 
	HGLOBAL m_hData; 
	LPBYTE  m_lpMemData; 
	BYTE byMaxBuf[MAXSIZE]; 
	LPBYTE m_lpBuffer; 
 
	int m_nTotalSize; 
 
	int nCurPos; //记下数据的位置 
 
	int nZipPos; //记下压缩数据的位置 
	int nBufPos; //记下当前存储位置hZip 
	int nZipSize; //压缩后数据的大小 
}; 
 
/////////////////////////////////////////////////////////////////////////////// 
//ARI Part END-------------------------------------------------------------- 
/////////////////////////////////////////////////////////////////////////////// 
 
/////////////////////////////////////////////////////////////////////////////// 
//LZW Part START-------------------------------------------------------------- 
/////////////////////////////////////////////////////////////////////////////// 
typedef struct LZWEncodeEntry 
{ 
	BYTE bLast; 
	WORD wCode; 
	struct LZWEncodeEntry far *pChild,*pRightBrother; 
}LZWENCODEENTRY,*PLZWENCODEENTRY;      
typedef struct LZWDecodeEntry 
{ 
	BYTE *pbContain; 
}LZWDECODEENTRY,*PLZWDECODEENTRY; 
 
class CLZWDecodeTable 
{ 
public: 
	CLZWDecodeTable(BOOL fInit=TRUE); 
	~CLZWDecodeTable(); 
	void ClearDecodeTable(void); 
	void InitLZWTable(void); 
	BYTE* GetMatchData(WORD wCode); 
	void AddToChild(WORD wCode,BYTE *pbContain,int iLength); 
	DWORD GetTableEntryNumber(void){return m_dwTableEntryNumber;}; 
protected: 
	BYTE** m_pbContain; 
	DWORD m_dwTableEntryNumber; 
}; 
 
class CLZWEncodeTable 
{ 
public: 
	CLZWEncodeTable(BOOL fInit=TRUE); 
	~CLZWEncodeTable(); 
	void ClearLZWTable(void); 
	void InitLZWTable(void); 
	PLZWENCODEENTRY FindMatchChild(BYTE bChileLast,PLZWENCODEENTRY pCurrent); 
	// return the find child 
	PLZWENCODEENTRY  AddToChild(BYTE bLast,PLZWENCODEENTRY pCurrent); 
	//return the add child 
 
public://inline 
	PLZWENCODEENTRY GetHead(void){return &m_EntryHead;}; 
	DWORD GetTableEntryNumber(void){return m_dwTableEntryNumber;}; 
 
protected: 
	void RemoveFirstChild(void); 
	PLZWENCODEENTRY FindRightBrother(PLZWENCODEENTRY pCurrent); 
protected: 
	DWORD m_dwTableEntryNumber; 
	UINT m_uNextCodeForUse; 
	LZWENCODEENTRY m_EntryHead; 
}; 
 
 
 
typedef BOOL (*FUN_LZWENCODEGETNEXTBYTE) (BYTE& bGet);// get next byte 
typedef BOOL (*FUN_LZWENCODEPUTNEXTBYTES) (BYTE* pbPut,int iLength); // put next byte 
typedef void (*FUN_LZWENCODEDBYTES) (void); 
typedef BOOL (*FUN_LZWDECODEGETNEXTBYTES) (BYTE* pbGet,int iLength); 
typedef BOOL (*FUN_LZWDECODEPUTNEXTBYTE) (BYTE bPut); 
typedef void (*FUN_LZWDECODEDBYTES) (void); 
 
#define LZW_MAX_ENTRY             		4096 
#define LZW_CLEAR_CODE                  256 
#define LZW_END_CODE                    LZW_CLEAR_CODE+1//257 
#define LZW_BEGIN_ENTRY                 LZW_END_CODE+1//258 
 
//#define SET_BIT_1(b,i)          (b |= (1<