亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? lz77.cpp

?? 數據傳輸時進行壓縮,大家可以參考一下,希望對你們有所幫助的.
?? CPP
字號:
//////////////////////////////
// LZ77.CPP
//////////////////////////////

#include <windows.h>
#include <stdio.h>
#include <memory.h>
#include <crtdbg.h>

#include "lz77.h"

/////////////////////////////////////////////////////////
// 取log2(n)的upper_bound
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;
}
// UpperLog2
/////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////
// 取log2(n)的lower_bound
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;
}
// LowerLog2
/////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// 將位指針*piByte(字節偏移), *piBit(字節內位偏移)后移num位
void CCompress::MovePos(int* piByte, int* piBit, int num)
{
	num += (*piBit);
	(*piByte) += num / 8;
	(*piBit) = num % 8;
}
// MovePos
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// 得到字節byte第pos位的值
//		pos順序為高位起從0記數(左起)
BYTE CCompress::GetBit(BYTE byte, int pos)
{
	int j = 1;
	j <<= 7 - pos;
	if (byte & j)
		return 1;
	else 
		return 0;
}
// GetBit
/////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////
// 設置byte的第iBit位為aBit
//		iBit順序為高位起從0記數(左起)
void CCompress::SetBit(BYTE* byte, int iBit, BYTE aBit)
{
	if (aBit)
		(*byte) |= (1 << (7 - iBit));
	else
		(*byte) &= ~(1 << (7 - iBit));
}
// SetBit
//////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////
// 將DWORD值從高位字節到低位字節排列
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;
}
// InvertDWord
//////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////
// CopyBits : 復制內存中的位流
//		memDest - 目標數據區
//		nDestPos - 目標數據區第一個字節中的起始位
//		memSrc - 源數據區
//		nSrcPos - 源數據區第一個字節的中起始位
//		nBits - 要復制的位數
//	說明:
//		起始位的表示約定為從字節的高位至低位(由左至右)
//		依次為 0,1,... , 7
//		要復制的兩塊數據區不能有重合
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);		
		// 如果還沒有復制完 nBitsToFill 個
		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;	// 已經填充了nBitsToFill位
		iByteDest++;
	}	
}
// CopyBits
/////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////
// CopyBitsInAByte : 在一個字節范圍內復制位流
// 參數含義同 CopyBits 的參數
// 說明:
//		此函數由 CopyBits 調用,不做錯誤檢查,即
//		假定要復制的位都在一個字節范圍內
void CCompress::CopyBitsInAByte(BYTE* memDest, int nDestPos, 
			  BYTE* memSrc, int nSrcPos, int nBits)
{
	BYTE b1, b2;
	b1 = *memSrc;
	b1 <<= nSrcPos; b1 >>= 8 - nBits;	// 將不用復制的位清0
	b1 <<= 8 - nBits - nDestPos;		// 將源和目的字節對齊
	*memDest |= b1;		// 復制值為1的位
	b2 = 0xff; b2 <<= 8 - nDestPos;		// 將不用復制的位置1
	b1 |= b2;
	b2 = 0xff; b2 >>= nDestPos + nBits;
	b1 |= b2;
	*memDest &= b1;		// 復制值為0的位
}
// CopyBitsInAByte
/////////////////////////////////////////////////////////


//------------------------------------------------------------------

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;
}

// 向索引中添加一個2字節串
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
	{
		// 對重復2字節串
		// 因為沒有虛擬偏移也沒有刪除操作,只要比較第一個節點
		// 是否和 off 相連接即可
		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;
		}
	}
}

//////////////////////////////////////////
// 將窗口向右滑動n個字節
void CCompressLZ77::_ScrollWindow(int n)
{	
	for (int i = 0; i < n; i++)
	{		
		nWndSize++;		
		if (nWndSize > 1)			
			_InsertIndexItem(nWndSize - 2);
	}
}

///////////////////////////////////////////////////////////
// 得到已經匹配了2個字節的窗口位置offset
// 共能匹配多少個字節
int CCompressLZ77::_GetSameLen(BYTE* src, int srclen, int nSeekStart, int offset)
{
	int i = 2; // 已經匹配了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;
}

///////////////////////////////////////////////////////////
// 在滑動窗口中查找術語
// nSeekStart - 從何處開始匹配
// offset, len - 用于接收結果,表示在滑動窗口內的偏移和長度
// 返回值- 是否查到長度為2或2以上的匹配字節串
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;
}

////////////////////////////////////////
// 輸出壓縮碼
// code - 要輸出的數
// bits - 要輸出的位數(對isGamma=TRUE時無效)
// isGamma - 是否輸出為γ編碼
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;
			// 輸出q個1
			CopyBits(dest + CurByte, CurBit, 
				pb, 0, q);
			MovePos(&CurByte, &CurBit, q);
		}
		// 輸出一個0
		out = 0;
		pb = (BYTE*)&out;		
		CopyBits(dest + CurByte, CurBit, pb + 3, 7, 1);
		MovePos(&CurByte, &CurBit, 1);
		if (q > 0)
		{
			// 輸出余數, q位
			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);
	}
}

/////////////////////////////////////////////
// 壓縮一段字節流
// src - 源數據區
// srclen - 源數據區字節長度
// dest - 壓縮數據區,調用前分配srclen+5字節內存
// 返回值 > 0 壓縮數據長度
// 返回值 = 0 數據無法壓縮
// 返回值 < 0 壓縮中異常錯誤
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))
		{			
			// 輸出匹配術語 flag(1bit) + len(γ編碼) + offset(最大16bit)
			_OutCode(dest, 1, 1, FALSE);
			_OutCode(dest, len, 0, TRUE);

			// 在窗口不滿64k大小時,不需要16位存儲偏移
			_OutCode(dest, off, UpperLog2(nWndSize), FALSE);
						
			_ScrollWindow(len);
			i += len - 1;
		}
		else
		{
			// 輸出單個非匹配字符 0(1bit) + char(8bit)
			_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;
}


/////////////////////////////////////////////
// 解壓縮一段字節流
// src - 接收原始數據的內存區
// srclen - 源數據區字節長度
// dest - 壓縮數據區
// 返回值 - 成功與否
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;

			// 在窗口不滿64k大小時,不需要16位存儲偏移
			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;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩视频一区二区在线观看| 国产一区91精品张津瑜| 日本精品视频一区二区三区| 国产日韩精品一区二区三区| 韩国欧美国产1区| 精品久久久久久久久久久院品网 | 欧美日韩日本视频| 亚洲欧美一区二区三区国产精品| 成人av片在线观看| 亚洲免费观看高清完整版在线观看 | 91免费在线播放| 亚洲天堂精品视频| eeuss鲁片一区二区三区在线观看| 在线电影国产精品| 乱一区二区av| 日本一区二区在线不卡| 99视频精品免费视频| 亚洲欧美日韩人成在线播放| 91久久精品一区二区三区| 亚洲欧美日韩中文字幕一区二区三区 | 欧美一二三区在线观看| 日韩成人午夜精品| 欧美大黄免费观看| 精品一区二区av| 国产人久久人人人人爽| 91社区在线播放| 性久久久久久久| 亚洲精品一区二区三区99| 岛国精品在线播放| 亚洲国产aⅴ成人精品无吗| 日韩欧美精品三级| 男女男精品视频| 国产欧美精品一区| 色猫猫国产区一区二在线视频| 亚洲成人动漫在线观看| 日韩欧美国产三级| av一二三不卡影片| 日本va欧美va瓶| 国产精品乱人伦中文| 欧美日韩在线免费视频| 九九九精品视频| 亚洲日本在线观看| 欧美日韩免费视频| 国产精品一二三在| 亚洲成人第一页| 欧美成人精品3d动漫h| 国产中文一区二区三区| 亚洲老司机在线| 精品国产免费一区二区三区四区| av在线播放成人| 首页综合国产亚洲丝袜| 国产精品久久午夜夜伦鲁鲁| 日韩一级片在线播放| 99久久伊人精品| 热久久一区二区| 亚洲欧美日韩国产综合在线| 欧美大片国产精品| 欧美无乱码久久久免费午夜一区| 久久精品理论片| 亚洲影院在线观看| 中文字幕成人网| 日韩一区国产二区欧美三区| 国产黄色成人av| 蜜臀a∨国产成人精品| 亚洲综合一区在线| 欧美激情综合在线| 欧美tk—视频vk| 欧美色图12p| 色综合色综合色综合| 国产精品一线二线三线精华| 一区二区日韩av| 亚洲国产精品高清| 2019国产精品| 欧美sm美女调教| 欧美日韩二区三区| 色哟哟一区二区在线观看| 成年人午夜久久久| 日本美女一区二区| 亚洲r级在线视频| 亚洲国产裸拍裸体视频在线观看乱了| 国产欧美一区二区精品仙草咪| 日韩欧美中文字幕公布| 91精品国产综合久久福利软件| kk眼镜猥琐国模调教系列一区二区 | 成人精品视频一区二区三区| 精品一区二区在线观看| 全国精品久久少妇| 免费人成精品欧美精品| 亚洲成人三级小说| 亚洲丝袜制服诱惑| 亚洲欧洲日韩女同| 亚洲区小说区图片区qvod| 国产精品乱码久久久久久| 国产三级三级三级精品8ⅰ区| 欧美精品一区男女天堂| 欧美日韩精品欧美日韩精品一| 成人午夜精品一区二区三区| 精品一区二区三区在线播放 | 精品理论电影在线观看| 欧美日韩精品一区二区三区| 精品视频在线免费| 91精品欧美久久久久久动漫| 91精品黄色片免费大全| 91精品国产aⅴ一区二区| 欧美日韩亚洲另类| 欧美另类一区二区三区| 欧美一二三四区在线| 久久午夜羞羞影院免费观看| 久久久国际精品| 国产性天天综合网| 自拍偷拍国产精品| 亚洲综合激情网| 免费成人在线网站| 国产成人高清在线| 91啪九色porn原创视频在线观看| 欧美亚洲综合网| 日韩一区二区电影在线| 欧美一区二区视频在线观看2020 | 日本久久一区二区| 欧美一区二区三区公司| 91免费看`日韩一区二区| 亚洲免费大片在线观看| 国产亚洲婷婷免费| 国产精品视频看| 亚洲一区二区三区四区五区黄| 欧美bbbbb| 91年精品国产| 26uuu成人网一区二区三区| 国产精品麻豆视频| 美女www一区二区| 在线观看视频一区| 国产三级欧美三级| 日韩和欧美的一区| 99精品偷自拍| 久久久影院官网| 欧美a级一区二区| 在线免费亚洲电影| 国产精品麻豆欧美日韩ww| 蜜芽一区二区三区| 欧美性一级生活| 日韩毛片精品高清免费| 国产经典欧美精品| 精品日韩一区二区| 天堂久久久久va久久久久| 色系网站成人免费| 国产欧美精品区一区二区三区| 久久国产麻豆精品| 欧美一区二区精品在线| 亚洲gay无套男同| 欧美三区在线视频| 亚洲自拍欧美精品| 欧美中文字幕亚洲一区二区va在线 | 国产在线播放一区| 欧美日韩在线精品一区二区三区激情 | 亚洲一区二区三区爽爽爽爽爽| 成人av网站大全| 欧美国产在线观看| 丁香一区二区三区| 国产日韩综合av| 国产不卡在线播放| 国产女人18毛片水真多成人如厕 | 亚洲不卡在线观看| 欧美色综合网站| 亚洲永久精品大片| 欧美视频一区二| 天堂一区二区在线免费观看| 欧美人伦禁忌dvd放荡欲情| 亚洲午夜av在线| 精品污污网站免费看| 亚洲成av人影院| 欧美精品日韩一本| 日本强好片久久久久久aaa| 日韩视频一区二区在线观看| 激情综合亚洲精品| 中文天堂在线一区| 92国产精品观看| 亚洲第一福利视频在线| 制服丝袜中文字幕亚洲| 老司机午夜精品| 久久久久久99久久久精品网站| 国产传媒日韩欧美成人| 亚洲色图在线视频| 欧美日韩国产a| 久久99精品国产.久久久久| 久久精品在这里| 色哟哟精品一区| 日本网站在线观看一区二区三区 | 亚洲第一综合色| 91精品在线免费观看| 国内欧美视频一区二区 | 日韩免费观看高清完整版在线观看| 裸体健美xxxx欧美裸体表演| 国产日韩欧美制服另类| 99久久99久久精品国产片果冻| 亚洲一区二区三区在线播放| 日韩一区二区三免费高清| 成人免费视频播放| 婷婷开心激情综合| 国产女同性恋一区二区| 欧美在线一二三|