Php 哈夫曼 压缩图片,快速Huffman解码
最近需要把采集到的圖像數據進行壓縮,節省存儲空間。綜合考慮壓縮比和速度,決定采用靜態Huffman編碼,使用預先計算好的字典對數據進行壓縮,這樣壓縮速度可以非常高,使用多線程之后可以進行實時壓縮,但解壓速度比較慢。
于是去gzip的代碼里面找了一下,在一個叫unpack.c的文件里發現了Huffman解碼的實現,gzip的解碼確實很高效,其中的原因,簡單來說就是多用內存,少用循環。
假設我們要壓縮的字符串是“ABBBCC”,計算得到Huffman編碼如下:
字符
計數
編碼
A
1
00
B
3
1
C
2
01
編碼后的二進制串是 0011101
要對編碼后的字符串進行解碼,比較容易想到的方法是這樣的,構造這么一個字典
編碼
字符
1
B
00
A
01
C
這個字典是原始的編碼表按字符編碼的長度進行排序,解碼的時候就在字典里面順序地查找編碼
對于這個例子而言是這樣一個過程
對二進制串0011101從左往右解碼,先嘗試編碼1(對應字符B),發現不對,因為最左邊是0,因此再嘗試字典的第二個編碼00(對應A),發現是正確的,最左邊就是00,因此解碼出字符A,將二進制串左移兩位得到11101,繼續從B的編碼1開始嘗試。最后能解碼出ABBBCC這個原始編碼。
這個解碼方法的問題就是每解碼一個字符串都要在字典里面循環一遍,效率不高。
gzip的方法
對于我們的例子gzip會構造這么一個字典
索引
索引編碼
編碼
字符
2
10
1
B
3
11
1
B
0
00
00
A
1
01
01
C
這個字典的特點就是有索引,因此查找編碼的時候不用循環,而是計算索引直接定位到對應的編碼。字典的構造方法是根據編碼生成索引編碼,所有索引編碼的長度是相同的,從二叉樹的角度來看就是把所有的子樹都補到同樣的長度,然后所有非編碼節點(如11)都和其父節點(如1)對應同一個字符(如B)。
這個方法同樣也是一種空間換時間的方法,隨著編碼長度的增加,內存消耗會指數增長,因此當編碼太長時,gzip會使用多個字典,將長編碼放在一些單獨的字典里面,減小內存消耗。
總結
以上是生活随笔為你收集整理的Php 哈夫曼 压缩图片,快速Huffman解码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: brew update 更新太慢
- 下一篇: python 方差分解_干货 :教你用P