GZIP壓縮原理分析(12)——第五章 Deflate算法詳解(五03) 預備知識(02) 壓縮“窗口”概念

壓縮的過程使用了“窗口”這一概念。壓縮時,將需要處理的數據拷貝到窗口中,然後直接在窗口中分析並處理這些數據。這個窗口就好比一張工作臺,每次把要處理的東西放到這張工作臺上,人們站在工作臺旁邊收拾這些數據,等到快收拾完的時候(還沒收拾完!!!),再去庫房把後面的數據取到工作臺上……基本就是這樣一個過程。需要注意的是,窗口的概念是貫穿壓縮始終的,真的就像個工作臺一樣。

 

在源碼中,指針window指向一塊內存,大小爲64KB,這就是“窗口”了。該窗口由兩部分構成,每部分大小爲WSIZE,每個WSIZE大小爲32KB。壓縮開始後,首先要讀一個窗口(讀64KB)的待壓縮數據到這個窗口中,如果沒有這麼多待壓縮數據,那就把當前所有的待壓縮數據全部讀到這個窗口中。接下來的壓縮過程就完全針對這個窗口中的數據展開。窗口按照大小被分成了兩個WSIZE,按照功能,窗口也同時被分成“查找緩衝區+先行緩衝區”兩部分。如下圖(a)和(b)所示,圖(a)是需要壓縮的全部原始數據,壓縮開始後,從原始數據中讀取整整一個window_size的數據到window這塊內存中,如圖(b)所示。此時這塊內存按照大小被分爲兩塊,每塊大小爲WSIZE;按照功能被分爲兩部分,查找緩衝區和先行緩衝區。

 

壓縮會逐字節處理先行緩衝區中的數據,每處理一個字節,先行緩衝區就減小一個字節,同時查找緩衝區就擴大一個字節,如圖(b)所示。壓縮剛開始的時候,按功能來分,此時窗口中只有先行緩衝區而沒有查找緩衝區,隨着壓縮的進行,查找緩衝區越來越大(但是最大不超過32KB,而先行緩衝區越來越小。

 (提示,這只是示意圖,圖中所示的尺寸只是爲了在這裏起到一個說明的作用)

 隨着壓縮的進行,先行緩衝區越來越小而查找緩衝區越來越大,直到先行緩衝區只剩MIN_LOOKAHEAD(這是源碼中使用的一個宏,這裏提前透露一下)這麼點時,如圖(c)所示,此時就要做一些特殊操作了。

 

當先行緩衝區只剩MIN_LOOKAHEAD這麼點時,此時先行緩衝區的第一個字節在WSIZE2中。從這個字節開始,跨過查找緩衝區中一個WSIZE大小的區間(連續的32KB),仍然無法到達window的起始位置(在圖c中是顯而易見的)。和WSIZE相比,MIN_LOOKAHEAD簡直小到不值一提,所以從先行緩衝區第一個字節開始在查找緩衝區中找連續的32KB,那麼這32KB中的絕大部分數據都在WSIZE2中,即,有(WSIZE - MIN_LOOKAHEAD)數據在WSIZE2中,而只有MIN_LOOKAHEAD這麼點數據在WSIZE1中。而且在查找緩衝區中尋找匹配串的時候,匹配串的出現位置通常不會跑到那麼遠。基於以上原因(MIN_LOOKAHEAD很小而且匹配串不會出現在那麼遠的地方),忽略掉WSIZE1中MIN_LOOKAHEAD數量的數據是完全沒有問題的,並且在WSIZE1中(WSIZE1 - MIN_LOOKAHEAD)數量的數據壓根不在查找緩衝區裏!!!所以,此時可以說,WSIZE1已經沒用了!

 

既然WSIZE1中的數據已經沒用了,那就把WSIZE2中的所有數據拷貝到WSIZE1中,再從原始待壓縮數據中讀取一個WSIZE的數據並將其拷貝到WSIZE2中,如圖(c)所示。這就是壓縮中窗口的使用原理。

 

窗口中的數據只是用來“掃描”用的,也就是說,窗口中的數據是用來分析的,不會改變窗口中的數據,當然,將WSIZE2的數據拷貝到WSIZE1的過程不能算作“改變”。窗口中的數據用來分析,而分析結果,也就是實際的壓縮結果,會被存儲到另外一塊內存中並輸出。這個過程後面還會具體分析,這裏提一下,爲後面做鋪墊。

 

這裏給查找緩衝區下個定義,後面就直接使用了。查找緩衝區:從先行緩衝區第一個字節開始,往已經完成處理的字節的方向算起,連續的一串數據稱爲查找緩衝區,查找緩衝區大小不超過32KB注意,與其他博客不同,我這裏故意避免提到“向前”以及“向後”的說法,因爲向前與向後理解起來太容易混亂。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章