LZO 使用和介紹


LZO說明

摘要

LZO 是一個用 ANSI C 語言編寫的無損壓縮庫。他能夠提供非常快速的壓縮和解壓功能。解壓並不需要內存的支持。即使使用非常大的壓縮比例進行緩慢壓縮出的數據,依然能夠非常快速的解壓。LZO 遵循 GNU 的 GPL 使用許可。

介紹

LZO 非常適合進行數據的實時壓縮解壓處理,這就是說他更關心操作速度,而不是壓縮比例。

LZO 使用 ANSI C 語言編寫,並且壓縮后的數據也被設計為可以跨平台使用的格式。

LZO 擁有如下的特點:

  • 解壓速度很快,並且很簡單;
  • 解壓時不需要內存支持;
  • 壓縮的速度還不錯;
  • 壓縮時只需要 64 KiB 的內存支持;
  • 壓縮比例可以根據需要調節,而這並不影響解壓的效率,提高壓縮比例自然會降低壓縮速度;
  • 壓縮包含了很多的壓縮級別,提供很多選擇;
  • 提供只需要 8 KiB 內存支持的壓縮級別;
  • 提供線程安全;
  • 提供無損壓縮;

LZO提供多重壓縮,和復原解壓;

設計標准

LZO 以處理速度為原則設計。解壓速度要快於壓縮速度。能夠提供給任何程序實時解壓的功能。LZO1X的解壓是按照 i386 編碼優化的。

事實上,是通過解壓算法定義的壓縮數據結構,最后采用手工測試數據驗證了這個結構。

效果

在古老的 Pentium 133 的設備上,我們運行了 Calgary Corpus 的測試數據。數據采用了 256 KiB的大小。

LZOxx-N 定義了使用的算法名稱,N代表壓縮級別。1-9 級別使用 64 KiB 內存,他主要提供更快的壓縮速度。99 級別使用 256 KiB 內存,提供更大的壓縮比例,但是處理速度依然很快。999 級別是按照壓縮比例優化的算法,他的壓縮速度很慢,並且使用大量的內存,這種級別一般用於生成預壓縮數據。

C 語言版本的 LZO1X-1 算法要比最快的 ZLIB 壓縮級別,快4-5倍的速度。當然他也在壓縮比例、壓縮時間、解壓時間方便優於 LZRW1-A 和 LZV 這些算法。

 +------------------------------------------------------------------------+
 | Algorithm        Length  CxB   ComLen  %Remn  Bits   Com K/s   Dec K/s |
 | ---------        ------  ---   ------  -----  ----   -------   ------- |
 |                                                                        |
 | memcpy()         224401    1   224401  100.0  8.00  60956.83  59124.58 |
 |                                                                        |
 | LZO1-1           224401    1   117362   53.1  4.25   4665.24  13341.98 |
 | LZO1-99          224401    1   101560   46.7  3.73   1373.29  13823.40 |
 |                                                                        |
 | LZO1A-1          224401    1   115174   51.7  4.14   4937.83  14410.35 |
 | LZO1A-99         224401    1    99958   45.5  3.64   1362.72  14734.17 |
 |                                                                        |
 | LZO1B-1          224401    1   109590   49.6  3.97   4565.53  15438.34 |
 | LZO1B-2          224401    1   106235   48.4  3.88   4297.33  15492.79 |
 | LZO1B-3          224401    1   104395   47.8  3.83   4018.21  15373.52 |
 | LZO1B-4          224401    1   104828   47.4  3.79   3024.48  15100.11 |
 | LZO1B-5          224401    1   102724   46.7  3.73   2827.82  15427.62 |
 | LZO1B-6          224401    1   101210   46.0  3.68   2615.96  15325.68 |
 | LZO1B-7          224401    1   101388   46.0  3.68   2430.89  15361.47 |
 | LZO1B-8          224401    1    99453   45.2  3.62   2183.87  15402.77 |
 | LZO1B-9          224401    1    99118   45.0  3.60   1677.06  15069.60 |
 | LZO1B-99         224401    1    95399   43.6  3.48   1286.87  15656.11 |
 | LZO1B-999        224401    1    83934   39.1  3.13    232.40  16445.05 |
 |                                                                        |
 | LZO1C-1          224401    1   111735   50.4  4.03   4883.08  15570.91 |
 | LZO1C-2          224401    1   108652   49.3  3.94   4424.24  15733.14 |
 | LZO1C-3          224401    1   106810   48.7  3.89   4127.65  15645.69 |
 | LZO1C-4          224401    1   105717   47.7  3.82   3007.92  15346.44 |
 | LZO1C-5          224401    1   103605   47.0  3.76   2829.15  15153.88 |
 | LZO1C-6          224401    1   102585   46.5  3.72   2631.37  15257.58 |
 | LZO1C-7          224401    1   101937   46.2  3.70   2378.57  15492.49 |
 | LZO1C-8          224401    1   100779   45.6  3.65   2171.93  15386.07 |
 | LZO1C-9          224401    1   100255   45.4  3.63   1691.44  15194.68 |
 | LZO1C-99         224401    1    97252   44.1  3.53   1462.88  15341.37 |
 | LZO1C-999        224401    1    87740   40.2  3.21    306.44  16411.94 |
 |                                                                        |
 | LZO1F-1          224401    1   113412   50.8  4.07   4755.97  16074.12 |
 | LZO1F-999        224401    1    89599   40.3  3.23    280.68  16553.90 |
 |                                                                        |
 | LZO1X-1(11)      224401    1   118810   52.6  4.21   4544.42  15879.04 |
 | LZO1X-1(12)      224401    1   113675   50.6  4.05   4411.15  15721.59 |
 | LZO1X-1          224401    1   109323   49.4  3.95   4991.76  15584.89 |
 | LZO1X-1(15)      224401    1   108500   49.1  3.93   5077.50  15744.56 |
 | LZO1X-999        224401    1    82854   38.0  3.04    135.77  16548.48 |
 |                                                                        |
 | LZO1Y-1          224401    1   110820   49.8  3.98   4952.52  15638.82 |
 | LZO1Y-999        224401    1    83614   38.2  3.05    135.07  16385.40 |
 |                                                                        |
 | LZO1Z-999        224401    1    83034   38.0  3.04    133.31  10553.74 |
 |                                                                        |
 | LZO2A-999        224401    1    87880   40.0  3.20    301.21   8115.75 |
 +------------------------------------------------------------------------+

注解:

  • CxB 是塊的數目;
  • K/s 是每秒處理 1KB 沒有壓縮的數據的速度;
  • 匯編的解壓速度將會更快;

簡單文檔

LZO 是塊壓縮算法,他壓縮和解壓一個塊數據。壓縮和解壓的塊大小必須一樣。

LZO 將塊數據壓縮成匹配數據(滑動字典)和非匹配的文字序列。LZO 對於長匹配和長文字序列有專門的處理,這樣對於高冗余的數據能夠獲得很好的效果,這樣對於不可壓縮的數據,也能得到較好的結果。

在處理不可壓縮數據時,LZO 將擴展輸入數據,每1024個字節最大增加 64 個字節。

我已經通過類似於 valgrind 這樣的內存檢查工具驗證過 LZO 程序,並且也使用了超過千兆字節的數據,進行各種參數調整,檢查過各種潛在的問題。LZO 目前不存在任何已知 BUG。

各種算法說明

這里實現了很多的算法,但是我希望提供沒有限制的向下兼容性,所以以后並不會取消現有的內容。

就像需要對象文件都是相對獨立的,若通過靜態鏈接使用 LZO 庫,只會增加很少的容量(大約幾KiB),以為內只要在真正使用 LZO 功能時這個模塊才會被加載。

1996年3月,我在 newsgroups.comp.compression 和 comp.compression.research 公布了 LZO1 和 LZO1A。他們主要處理了兼容性的問題。LZO2A解壓的速度非常慢,並且也沒有能提供一個較快的壓縮速度。

在我的試驗中可以看到,LZO1B適合處理大量的數據,或者有高冗余性的數據。LZO1F適合處理小量數據和二進制數據。LZO1X適合各種環境。LZO1Y 和 LZO1Z 跟 LZO1X 很相像,他們能夠在一些環境中達到更好的壓縮比例。

請注意,你有很多的選擇。

使用 LZO 庫

無論數據的大小,使用 LZO 庫的基本功能非常的簡單。我們假設你打算使用 LZO1X-1的算法處理你的數據。

壓縮

1 include <lzo/lzo1x.h>  
2 call lzo_init ()  
3 通過 lzo1x_1_compress () 壓縮你的數據  
4 編譯連接 LZO 庫  

解壓

1 include <lzo/lzo1x.h>  
2 call lzo_init ()  
3 通過 lzo1x_decompress () 解壓數據  
4 編譯連接 LZO 庫  


在源碼包的 examples/simple.c 有完整的范例代碼。也可以查看 LZO.FAQ 獲得更多內容。

原始文件:

LZO FAQ

  1. 我不想閱讀文檔,指向知道如何將這個功能添加到我的程序中

    有兩個范例:examples/simple.c 和 examples/lzopack.c 提供了簡單使用的方法。

    但是最好還是將整個的文檔閱讀完成,會幫助你更好的使用。

  2. 你能解釋一下各種算法名稱的含義嗎?

    我們用 LZO1X 來舉例說明:

    算法名稱:LZO1X

    算法分類:LZO1

    然后提供了很多的壓縮級別:

         LZO1X-999
            !---------- 算法分類
             !--------- 算法類型
               !!!----- 壓縮級別 (1-9, 99, 999)
         LZO1X-1(11)
            !---------- 算法分類
             !--------- 算法類型
               !------- 壓縮級別 (1-9, 99, 999)
                 !!---- 內存級別 (壓縮時所需要的內存)
    
    在一個壓縮類型中,不同的壓縮級別和內存級別的數據結構是相同的,所以 LZO1X 的解壓方法,能夠適用於 LZO1X-** 對應的所有壓縮算法。
    LZO1 分類:使用嚴格的 BTYE 校驗的 壓縮數據結構
    LZO2 分類:使用 bit 位移方式,解壓速度比較慢。
  3. 為什么有這么多的算法?

    由於很多的歷史版本,而我希望能夠提供良好的向下兼容性,所以擁有這么多算法。不必擔心整個庫的大小問題,使用其中一種算法,只會給你的程序添加很少的幾個 KiB。

    如果你只是希望給你的程序添加一個簡單的壓縮功能,你可以查看 miniLZO 部分,在 minilzo/README.LZO 中,可以查看更纖細的信息。

  4. 我應該使用哪種算法?

    LZO1X 在很多情況下都是一個比較好的選擇。所以,追求速度可以使用 LZO1X-1,生成預壓縮文件可以使用 LZO1X-999,如果你有很多的內存,可以使用 LZO1X-1(11) 或者 LZO1X-1(12)。

    當然這里有很多的選擇,你可以根據自己的需要進行選擇。也可以嘗試一下 LZO1Y 或者 LZO1F 等等。

  5. 在解壓的時候,每種方式有什么區別?

    我們還是使用 LZO1X 作為范例來說明:

    • lzo1x_decompress

      他能夠提供較快的解壓速度,這是一個標准的解壓方式。但是他不提供附加的相關數據安全檢查,他默認處理的數據是完成的壓縮后數據。如果數據由於各種原因損壞,例如硬盤損壞或者傳輸過程中的錯誤而破損,那么他可能直接產生嚴重錯誤,而終止你的程序。

    • lzo1x_decompress_safe

      這是一個安全的解壓方式,但是他會慢一些。他會捕捉解壓中的數據問題,並且返回相關的錯誤信息,而避免產生嚴重錯誤。

    • lzo1x_decompress_asm

      一個類似於 lzo1x_decompress 的方式,但是是通過匯編實現的。

    • lzo1x_decompress_asm_safe

      一個類似於 lzo1x_decompress_safe 的方式,但是是通過匯編實現的。

    • lzo1x_decompress_asm_fast

      類似於 lzo1x_decompress_asm 方式,但是能夠提供更快的速度。為了提高速度,他會在解壓后的數據結尾添加 3 BYTE 的數據。因為這種方式按照 32 bit 作為一個單位進行數據處理。

      當你從一個內存塊解壓數據到另外一個內存塊,需要多提供 3 BYTE 的數據存儲空間。如果你要直接解壓一個視頻內容,不要使用這種方式,因為最后添加的 3 BYTE 的內容會被當成顯示內容處理。

    • lzo1x_decompress_asm_fast_safe

      這是一個 lzo2x_decompress_asm_fast 的安全版本。

    這里請注意如下內容:

    • 當使用安全類型的解壓方式時,要通過 dst_len 參數說明 dst 參數可以放置的數據最大容量。
    • 如果你希望確認你的壓縮后的數據是安全的,請使用 MD5 之類的檢查,當然若使用安全類型的方式不需要這個檢查。因為在安全方式中,任何錯誤都回被捕捉並返回。
    • 匯編版本只能在 i386 的架構中使用,具體的信息可以查看 asm/i386/OOREADME.TXT 文件中查看相關內容。
    • 你可能需要測試一下匯編版本是否比C語言版本速度更快,有些編譯器能夠完成很好的優化工作,使得C語言版本能夠工作的很好。
  6. 優化處理了哪些東西?

    壓縮采用了啟發式方法,他們有時記錄信息,這不能提高壓縮比例。優化去處了這些不必要的信息,來提高解壓速度。

    在解壓時,同樣也不處理這些可能記錄壓縮內容變化的內容。壓縮后的數據在一些 bit 中會重新排列,這不會引起壓縮后數據的容量變化。

    經過優化處理以后,解壓速度可以提升 1-3%。優化沒有更多的效果提升了。

  7. 我需要更快的解壓速度

    在很多 RISC 處理其中(例如MIPS),針對 32-bit WORD 的傳送速度要快於 BYTE,這能夠有效的提高解壓速度。所以在驗證完其他部分工作正常后,你可以在LZO1X 和LZO1Y 兩種算法的解壓時,采用 LZO_ALIGNED_OK_4 來提高效率。變更 config.h 中相關的內容,並且重新編譯所有東西,以使用它。

    在 i386 的架構中,你可以嘗試使用匯編版本。

  8. 我如何在壓縮或者解壓時減少內存的使用?

    如果你能夠聰明的控制數據的范圍,那么你可以在解壓縮的時候,使用壓縮使用的內存。這樣能夠有效的移除保存壓縮后的數據的內存。這需要你了解對於可執行包裹的基礎了解。

    當然你也可以部分的重用壓縮時的BUFF

    在 examples/overlap.c 的范例中,可以看到更詳細的內容。

  9. 我能獲得一個關於預壓縮的相關指導嗎?

    在算法 LZO1X-999 的情況下:

    預壓縮步驟:

    1 call lzo_init()  
    2 call lzo1x_999_compress ()  
    3 call lzo1x_optimze ()  
    4 對於壓縮后的數據做一個 32長度的 MD5  
    5 將壓縮后的數據和對應的MD5保存在一個文件中  
    6 如果你還不放心,可以現在進行一次解壓驗證  
    解壓步驟:
    1 call lzo_init ()  
    2 裝載你的壓縮數據和對應的 MD5  
    3 通過 MD5 驗證你的壓縮后的數據  
    4 解壓  
    可以在 examples/precomp.c 和 examples/precomp2.c 的代碼中查看到更詳細的范例。
  10. 壓縮以后,我的數據會增長多少?

    LZO 對於不可壓縮的數據,會增加一點容量。我一直沒有計算過精確的數字,但是下面列出了最浪費的情況下的公式:

    壓縮算法:LZO1,LZO1A,LZO1B,LZO1C,LZO1F,LZO1X,LZO1Y,LZO1Z

    1 output_block_size = input_block_size + (input_block_size / 16) + 64 + 3  
    這大約是原始數據的106%。

    壓縮算法:LZO2A

    1 output_block_size = input_block_size + (input_block_size / 8) + 128 + 3  

原始文件:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM