GZIP壓縮原理分析(13)——第五章 Deflate算法詳解(五04) 預備知識(03) 遊程編碼

有關遊程編碼的定義,在網上有很多較爲專業的版本,但我覺得那些較爲專業的版本就是把簡單的東西搞複雜然後看起來高大上罷了,入門太麻煩。這裏我們沿用本章開始提到的那篇博客中的內容:“什麼叫遊程呢?就是一段完全相同的數的序列。什麼叫遊程編碼呢?說起來原理更簡單,就是對一段連續相同的數,記錄這個數一次,緊接着記錄出現了多少個即可。”,這樣說多淺顯易懂。舉個簡單的例子,有如下數列,

1,1,1,1,2,2,2,2,2,2,2,2,4,4,4,4,9,9,9,9,9,9,9,9;

1出現了四次,重複了三次(後面那三個1算作“重複”,注意出現次數重複次數的差別),2出現了八次,重複了七次,4出現了四次,重複了三次,9出現了八次,重複了七次。對其用使用遊程編碼,就是

1*3,2*7,4*3,9*7;

其中,用“*”將實際的數與該數重複的次數區分開來。從上例可以看出,遊程編碼對這種連續重複出現的數據有很好的壓縮效果。注意,我這裏使用“*”作爲標記只是作爲一個例子,用這種方式進行遊程編碼也只是一個例子,但是符合規則,各位看官不要以爲遊程編碼一定是這麼來操作的,遊程編碼沒有這麼死板,只要符合上面的基本定義即可,具體怎麼操作視情況而定。

 

在deflate算法中,相應的遊程編碼有專門的使用細則,這裏我只講是什麼,後面再講爲什麼,各位看官這裏要做的只是瞭解deflate如何使用遊程編碼以及使用細則,會用即可,後面會詳細分析這塊內容。

 

Deflate算法中的遊程編碼只對0~15這十六個數進行遊程編碼(只有這十六個數,不要管爲什麼,後續會講),而且只對重複次數不小於三次(那麼這個數據的總的出現次數就不能小於四次)時才使用遊程編碼:

 i.  用“16”充當上文例子中的“*”,但是這個“16”只給1~15使用。“16”後面就是表示重複次數(注意區分“出現次數”)的數據,用2bit(兩比特)記錄,分別是“00,01,10,11”,對應的重複次數分別爲“3,4,5,6”(重複次數不小於三次,所以這裏從3開始,因爲只用兩位記錄,所以最大的重複次數是6),如果6次之後緊跟着還有重複,那麼就再來一個“16”並且後面跟着實際的重複次數即可;

ii. “17”專門給0使用,所以不需要類似“*”的標誌來隔開被編碼數據與重複次數。“17”後面跟3bit(三比特),對應用二進制表示的閉區間[000, 111],表示0的連續出現次數爲閉區間[3, 10]次;

iii. “18”專門給0使用,所以不需要類似“*”的標誌來隔開被編碼數據與重複次數。“18”後面跟7bit(七比特),對應用二進制表示的閉區間[0000000, 1111111],表示0的連續出現次數爲閉區間[11, 138]次。

 

例如,有如下經過遊程編碼的數據,請將其解開,

4, 16, 1, 3, 3, 3, 6, 16, 3, 16, 0, 17, 3, 2, 16, 0

a)  看到“4, 16, 1”,這是對4進行遊程編碼的結果,1表示4的重複次數爲四次,即4的出現次數爲五次,所以對這三個數解碼就是“4, 4, 4, 4, 4”;

b)  看到“3, 3, 3”,就是實際的“3, 3, 3”,未經過遊程編碼;

c)  看到“6, 16, 3, 16, 0”,這是對6進行遊程編碼的結果,3表示6的重複次數爲六次,後面還有一個“16”,說明後面的0仍然表示6的重複次數,0即表示6重複了三次,所以6總共重複了九次,總共出現了十次,即“6, 6, 6, 6, 6, 6, 6, 6, 6, 6”;

d)  看到“17, 3”,表示0一共出現了六次,即“0, 0, 0, 0, 0, 0”;

e)  看到“2, 16, 0”,即“2, 2, 2, 2”。

 

從上例我們可以看出,“16”要帶着“被編碼數”和“被編碼數的重複次數”,而17和18因爲專門表示0的出現次數,所以只要帶着“出現次數”即可。因爲“重複次數”和“出現次數”都從3開始,而實際用來表示這兩個含義的數據卻從0開始(“18”其實是“17”的延續),所以我們在根據重複次數或出現次數手動計算實際值的時候,直接“加三”即可,例如“6, 16, 3”,直接用重複次數3再加上3就是實際的重複次數六了;再比如“17, 3”,用出現次數3加上3就是實際出現次數六了。

 

總結,這裏我們介紹了遊程編碼的基本原理並瞭解了deflate中游程編碼的實現方式。主要還是想強調一下“重複次數”與“出現次數”的不同,這兩個概念搞不清,計算“16”的遊程編碼時往往就少計算一次!!!而且一個被編碼數後面可能連續出現多個16,比如“5, 16, 3, 16, 3, 16, 3, 16, 3, 16, 0”。這裏再總結一下這三條細則:

i.  16後面跟2bit 表示[1,15]15個被編碼數的重複次數爲[3, 6],對應二進制所表示的十進制數範圍(即16後面跟着的數的範圍)[0, 3],被編碼數要出現在“16”前面;

ii. 17後面跟3bit 0連續出現次數[3,10]17後面那個數的範圍[0, 7],被編碼數0就不出現了;

iii. 18後面跟7bit 0連續出現次數[11,138]18後面那個數的範圍[0, 127],被編碼數0就不出現了。

 

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