常用資料壓縮庫的編譯與使用
由于在工作中有用到資料壓縮的功能,我便查找了一些壓縮函數庫,對這些函數庫進行了簡單的實驗,簡要對比了各自的性能。在這裡,我既是對以前工作的總結,也同時希望能給其他人帶來一些幫助。
首先,因為我工作中使用的環境是嵌入式Linux系統,采用的是C語言,是以我在選擇壓縮函數庫的時候主要是選擇一些能交叉編譯的函數庫。我前後共實驗了三種函數庫,分别是:LZO、ZILB和LZMA。分别在Windows平台和嵌入式Linux平台實驗。由于我對壓縮算法并沒有深入的了解,實驗的結果也不能確定一定正确,僅僅為作為一個參考。
1. 資料壓縮庫簡介
1.1 LZO庫簡介
LZO庫在描述自己的時候使用的是“實時資料壓縮庫”(a real-time data compression library),這就意味着LZO庫是更加重視資料壓縮的速度。該項目的首頁是http://www.oberhumer.com/opensource/lzo/,LZO 遵循 GNU 的 GPL 使用許可。
LZO庫最初采用ANSI C編寫,是一個無損壓縮庫。它提供多個壓縮函數接口,要得到高的壓縮率,就會降低壓縮速度,然而,解高壓縮率的資料并沒有明顯速度。詳細的說明可以參考其工程目錄下的doc/LZO.TXT檔案,這裡簡單列出該壓縮庫的一些特點:
1、解壓速度非常快,解壓不需要額外的記憶體空間。
2、壓縮速度也非常快,壓縮隻需要64k的記憶體。
3、提供函數接口用來犧牲速度來換取高壓縮率,但解壓速度不降低。
4、有僅僅需要8k記憶體的壓縮算法。
5、算法是線程安全的無損壓縮算法。
1.2 ZLIB庫簡介
ZLIB庫是一個通用的資料壓縮庫,它幾乎已經成為了一個業界的标準,在許多軟體中得到應用。該項目的首頁是http://www.zlib.net/,ZLIB是自由軟體,使用ZLIB授權。
ZLIB資料壓縮庫同樣是一個無損壓縮庫,對線程也是安全的。它提供資料壓縮接口,同時也提供了gzip檔案的讀寫接口。函數庫提供了對處理器和記憶體使用控制的能力,可以在諸如嵌入式系統這樣記憶體有限制的環境中是有用的。詳細的說明可以參考其工程目錄下doc目錄中的文檔。
1.3 LZMA庫簡介
LZMA是一個Deflate和LZ77算法改良和優化後的壓縮算法庫,具有很高的壓縮比。2001年被首次應用于7-Zip壓縮工具中,是 2001年以來得到發展的一個資料壓縮算法。項目首頁為http://www.7-zip.org/sdk.html,LZMA是公開的壓縮庫。
LZMA庫具有高的壓縮比和較快的速度,解壓代碼和占用的記憶體都比較小。其壓縮所需要的記憶體是:字典大小*11.5+6M+狀态大小。解壓需要的記憶體是:字典大小+狀态大小。詳細的說明可以參考其工程目錄下doc目錄中的文檔。
2 資料壓縮庫的編譯方法
由于我要測試Windows平台和嵌入式Linux平台下的運作情況,是以這裡隻是列舉這兩個平台的編譯方法。編譯的目标是靜态庫,這裡列舉的方法可能不是最簡單的編譯方法,如果你有更加友善或規範的編譯方法請與我聯系。
2.1 LZO庫的編譯
我使用的LZO庫的版本是2.09
- Windows平台編譯
在LZO工程檔案中目錄B/win32和B/win64目錄中有編譯的批處理檔案,可是我在實際使用的過程中不能正确執行,不知道是不是哪裡出了問題,我使用的方法是建立立一個VS工程,包含工程目錄下的src和include目錄生成靜态庫檔案,最終編譯出了LZO的Windows靜态庫。
- 交叉編譯
LZO的交叉編譯時非常簡單的,隻要進入LZO的目錄,依次輸入一下指令就可以完成LZO的交叉編譯。
1、設定編譯器: export CC=你的編譯器。
2、設定AR程式:export AR=你的AR程式。
3、設定安裝目錄./configure --host=arm-linux --prefix=$PWD/amr_install/
4、執行make指令。
5、執行make install指令。
在這些指令都執行完成之後,LZO的靜态庫和頭檔案就會放在工程目錄的amr_install檔案夾中。在執行make install可能會出現錯誤,我在執行過程中就出現了chmod無法更改權限的錯誤,可能是因為我使用虛拟機編譯的原因,不過無所謂,自己複制一下就好啦。
2.2 ZLIB庫的編譯
我使用的ZLIB庫版本是1.2.8
a) Windows平台下編譯
ZLIB的Windows下編譯很簡單,在ZLIB的工程目錄下contrib/vstudio/目錄中有vc9、vc10、vc11三個檔案夾。分别對應不同的VS版本,我安裝的是VS2013可以打開vc11。其中的zlibstat工程是用來編譯靜态庫的,隻需選中工程點選生成即可。另外,在ZLIB靜态庫使用的過程中可能會出現函數找不到實作這樣的情況,出現這個問題的原因很可能是__stdcall調用和__cdecl調用的問題。解決方法是講zconf.h中的
# defineZEXPORTWINAPI
改為:
# defineZEXPORTWINAPIV
然後重新編譯靜态庫即可。
b) 交叉編譯
ZLIB的交叉編譯與LZO類似,依次執行以下幾條指令即可:
1、設定編譯器: export CC=你的編譯器。
2、設定AR程式:export AR=你的AR程式。
3、設定安裝目錄 ./configure--prefix=$PWD/amr_install/
4、執行make指令。
5、執行make install指令。
在這些指令都執行完成之後,ZLIB的靜态庫和頭檔案就會放在工程目錄的amr_install檔案夾中。在執行make指令時也可能會出現chmod無法更改權限的錯誤,可能是因為我使用虛拟機編譯的原因。我最後就隻執行了make libz.a指令然後自己動手複制的。
2.3 LZMA庫的編譯
我使用的LZMA庫的版本是15.06 beta。
a) Windows平台下編譯
關于LZMA庫的編譯,我查了一些資料,都不能實際操作成功,于是我采用了最笨的方法,将工程目錄下C檔案夾下的所有頭檔案和C檔案全部複制出來,在VS中建立一個靜态庫工程,編譯出靜态庫。
b) 交叉編譯
交叉編譯我同樣不能找到一個我能成功執行的方法,也是采用了複制所有的頭檔案和C檔案,編寫makefile。然而并沒有那麼順利,編譯過程中出現了許多的錯誤。我試圖解決這些錯誤,發現大部分還是平台的原因。應該是還有哪些宏開關沒有配置或修改,由于時間的原因,就沒有深入研究,以後有時間在來解決這個問題吧。
3 資料壓縮庫的簡單使用
3.1 LZO庫的使用
LZO庫提供一系列的資料壓縮函數,不同的壓縮函數代表着不同的壓縮方法或不同的壓縮等級,當然具有不同的壓縮比和壓縮時間。不同等級的壓縮函數往往使用相同的解壓函數進行解壓。具體的資料壓縮函數和壓縮等級可以參考/doc/LZO.TXT中給出的表格(見下圖)。簡單的測試代碼在examples/ simple.c檔案中。
LZO壓縮函數一般有5個參數:
1、輸入資料緩存指針。
2、輸入資料長度。
3、輸出資料緩存指針。
4、輸出緩存區長度指針、壓縮後的資料長度(傳入輸出緩存區長度,輸出壓縮後的資料長度)。
5、壓縮過程額外需要的記憶體指針(在對應的頭檔案有定義)。
LZO解壓函數一般也有5個參數:
1. 輸入資料緩存指針。
2. 輸入資料長度。
3. 輸出資料緩存指針。
4. 輸出緩存區長度指針、解壓後的資料長度(傳入輸出緩存區長度,輸出解壓後的資料長度)。
5. 解壓過程額外需要的記憶體指針(沒有用,一般傳入null)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jN4EjM0YTMxITMwETM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
3.2 ZLIB庫的使用
ZLIB提供的壓縮函數主要是compress和compress2,其中compress是compress2設定壓縮等級為預設值(預設值為6)的情況。解壓函數是uncompress。其用法也是十分簡單,和LZO基本一樣。隻是前兩個參數是輸出相關的中間兩個參數是輸入相關的,最後一個是壓縮等級。解壓函數隻有四個參數。簡單的測試用例參考test/ example.c。
3.3 LZMA庫的使用
對于LZMA庫可以使用LzmaCompress進行資料壓縮,使用LzmaUncompress進行資料解壓。其中壓縮函數的參數清單比較複雜有13個參數,解壓函數有6個參數。
首先,先看一下壓縮函數的參數:
1~4:輸入輸出資料相關的參數。
5~6:prop變量相關的參數,至于prop可以了解為壓縮所産生的附加資訊,後面解壓的時候需要用到sizeProp必須為5。
7: level 壓縮等級0 <= level <= 9, default = 5。
8: dictSize 字典大小 default = (1 <<24) 就是2^24bit
其他在lzmalib.h中有詳細的說明,使用者可以參考
解壓函數就比較簡單了,輸出輸入和prop變量。這裡的prop必須是壓縮函數輸出的變量。
4 資料壓縮庫的實驗結果
Windows下的實驗結果:(2.36GHz雙核CPU,2G記憶體)
AMR下實驗結果:(AMR9 9G25晶片)