天天看點

compress uncompress函數

zlib 是通用的壓縮庫,提供了一套 in-memory 壓縮和解壓函數,并能檢測解壓出來的資料的完整性(integrity)。zlib 也支援讀寫 gzip (.gz) 格式的檔案。下面介紹兩個最有用的函數——compress和uncompress。

int compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);

compress函數将source緩沖區中的内容壓縮到dest緩沖區。sourceLen表示source緩沖區的大小(以位元組計)。注意函數的第二個參數destLen是傳址調用。當調用函數時,destLen表示 dest 緩沖區的大小,destLen > (sourceLen + 12)*100.1%。當函數退出後,destLen表示壓縮後緩沖區的實際大小。此時destLen / sourceLen正好是壓縮率。

compress若成功,則傳回 Z_OK;若沒有足夠記憶體,則傳回Z_MEM_ERROR;若輸出緩沖區不夠大,則傳回Z_BUF_ERROR。

int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);

uncompress函數将source緩沖區的内容解壓縮到dest緩沖區。sourceLen是source緩沖區的大小(以位元組計)。注意函數的第二個參數destLen是傳址調用。當調用函數時,destLen表示dest緩沖區的大小,dest緩沖區要足以容下解壓後的資料。在進行解壓縮時,需要提前知道被壓縮的資料解壓出來會有多大。這就要求在進行壓縮之前,儲存原始資料的大小(也就是解壓後的資料的大小)。這不是 zlib 函數庫的功能,需要我們做額外的工作。當函數退出後,destLen是解壓出來的資料的實際大小。

uncompress若成功,則傳回 Z_OK;若沒有足夠記憶體,則傳回Z_MEM_ERROR;若輸出緩沖區不夠大,則傳回Z_BUF_ERROR。若輸入資料有誤,則傳回Z_DATA_ERROR。

zlib 帶的example.c是個很好的學習範例,值得一觀。我們寫個程式,驗證 zlib 的壓縮功能。所寫的測試程式儲存為 testzlib.cpp,放在zlib-1.1.4 目錄下。程式源代碼:

// testzlib.cpp  簡單測試 zlib 的壓縮功能

#include <cstring>

#include <cstdlib>

#include <iostream>

#include "zlib.h"

using namespace std;

int main()

{

    int err;

   Byte compr[200], uncompr[200];    // big enough

    uLong comprLen, uncomprLen;

    const char* hello = "12345678901234567890123456789012345678901234567890";

    uLong len = strlen(hello) + 1;

    comprLen  = sizeof(compr) / sizeof(compr[0]);

    err = compress(compr, &comprLen, (const Bytef*)hello, len);

    if (err != Z_OK) {

        cerr << "compess error: " << err << '\n';

        exit(1);

    }

    cout << "orignal size: " << len

         << " , compressed size : " << comprLen << '\n';

    strcpy((char*)uncompr, "garbage");

    err = uncompress(uncompr, &uncomprLen, compr, comprLen);

        cerr << "uncompess error: " << err << '\n';

         << " , uncompressed size : " << uncomprLen << '\n';

    if (strcmp((char*)uncompr, hello)) {

        cerr << "BAD uncompress!!!\n";

    } else {

        cout << "uncompress() succeed: \n" << (char *)uncompr;

}

編譯執行這個程式,輸出應該是

D:\libpng\zlib-1.1.4>bcc32 testzlib.cpp zlib.lib

D:\libpng\zlib-1.1.4>testzlib

orignal size: 51 , compressed size : 22

orignal size: 51 , uncompressed size : 51

uncompress() succeed:

12345678901234567890123456789012345678901234567890