zlib庫 安裝與使用

1. zlib簡介

zlib 適用於數據壓縮的函式庫,由Jean-loup Gailly (負責compression)和 Mark Adler (負責decompression)開發。 
  zlib被設計成一個免費的、通用的、法律上不受阻礙(即沒有被任何專利覆蓋) 的無損數據壓縮庫。zlib幾乎適用於任何計算器硬件和操作系統。
  zlib本身的數據格式可以進行跨平臺的移植。 與在Unix上適用的LZW壓縮方法 以及 GIF 圖像壓縮不同, zlib中適用的壓縮方法從不對數據進行拓展。(LZW在極端情況下會導致文件大小變爲原來的兩倍、甚至三倍)。zlib的內存佔用也是獨立於輸入數據的,並且在必要的情況下可以適當減少部分內存佔用。

2. zlib的安裝

首先, 下載zlib, 當前最新的 版本應該是1.2.8. 並解壓

windeal@ubuntu:opensource$ wget https://sourceforge.net/projects/libpng/files/zlib/1.2.8/zlib-1.2.8.tar.gz/download -o zlib-1.2.8.tar.gz
windeal@ubuntu:opensource$ tar zvfx zlib-1.2.8.tar.gz

進入zlib目錄,執行以下命令安裝zlib

windeal@ubuntu:zlib-1.2.8$ ./configure
windeal@ubuntu:zlib-1.2.8$ make 
windeal@ubuntu:zlib-1.2.8$ make check
windeal@ubuntu:zlib-1.2.8$ sudo make install

make install這一步,由於要把zlib安裝到/usr/local/lib 路徑下,所以可能需要root 權限。
安裝成功後,可以在/usr/local/lib下找到 libz.a

libz.a是一個靜態庫,爲了使用zlib的接口,我們必須在連接我們的程序時,libz.a鏈接進來。
只需在 鏈接命令後加-lz /usr/llocal/lib/libz.a 即可。

舉個例子, 我們有一個使用zlib庫的應用程序, 源文件只有一個:zpipe.c, 裏面調用了zlib的接口,這時執行以下命令編譯既可:

windeal@ubuntu:examples$ gcc -o zpipe.o -c zpipe.c
windeal@ubuntu:examples$ gcc -o zpipe zpipe.o -lz /usr/local/lib/libz.a 

zlib 提供了一系列用於壓縮和解壓的函數接口, 具體的含義可以參考zlib manual

3. zlib的使用

zlib 在 examples 路徑下提供了許多使用zlib的例子:

windeal@ubuntu:examples$ ls
enough.c  fitblk.c  gun.c  gzappend.c  gzjoin.c  gzlog.c  gzlog.h  README.examples  zlib_how.html  zpipe.c  zran.c
windeal@ubuntu:examples$ 

README.examples 有介紹各個example的作用。
這些例子已經大概說明了zlib的基本用法。

##3.1 compress 與 uncompress
compressuncompress是zlib最基本的兩個函數了。他們分別用於壓縮和解壓數據。 原型如下:

ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
                                 const Bytef *source, uLong sourceLen));
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
                                   const Bytef *source, uLong sourceLen));

參數類型Bytef表示字節流,它與字符串有所不同,字節流沒有結束符,因而需要配備長度信息,處理字符串的時候需要把結束符也當成一個普通的字節。 而uLongf則用於指明長度信息了, 其實相當於unsigned long

看下面的例子:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#include <zlib.h>
 
 
int main(int argc, char *argv[])
{ 
    char inbuf[] = "Hello, This is a demo for compress and uncompress interface!\n"
                 "Written by windeal.li\n"
                 "email: [email protected]\n";
    uLong inlen = sizeof(inbuf);
    char *outbuf = NULL;
    uLong outlen;
 
    outlen = compressBound(inlen);
    printf("in_len: %ld\n", inlen);
    printf("out_len: %ld\n", outlen);
 
    if ((outbuf = (char *)malloc(sizeof(char) * outlen)) == NULL){
        fprintf(stderr, "Failed to malloc memory for outbuf!\n");
        return -1;
    }
 
    /* compress */
    if (compress(outbuf, &outlen, inbuf, inlen) != Z_OK) {
        fprintf(stderr, "Compress failed!\n");
        return -1;
    }
    printf("Compress Sucess!\n");
    printf("\routlen:%ld, outbuf:%s\n", outlen, outbuf);
  
    memset(inbuf, 0, sizeof(inbuf));
    /* Uncompress */
    if (uncompress(inbuf, &inlen, outbuf, outlen) != Z_OK){
        fprintf(stderr, "Uncompress failed!\n");
        return -1;
    }
    printf("Uncompress Success!\n");
    printf("\rinlen:%ld, inbuf:%s\n", inlen, inbuf);
 
    /* free memory */
    if (outbuf != NULL){
        free(outbuf);
        outbuf = NULL;
    }
 
    return 0;
}

3.2 infate、deflate、z_stream介紹

這裏infatedefate 其實是指兩組函數

  • deflateInit() + deflate() + deflateEnd()用於完成流的壓縮
  • inflateInit() + inflate() + inflateEnd()用於完成解壓縮功能

z_stream是上面兩組函數中用到的,用來表示流的數據結構。

typedef struct z_stream_s {
    z_const Bytef *next_in;     /* next input byte */
    uInt     avail_in;  /* number of bytes available at next_in */
    uLong    total_in;  /* total number of input bytes read so far */
 
    Bytef    *next_out; /* next output byte should be put there */
    uInt     avail_out; /* remaining free space at next_out */
    uLong    total_out; /* total number of bytes output so far */
 
    z_const char *msg;  /* last error message, NULL if no error */
    struct internal_state FAR *state; /* not visible by applications */
 
    alloc_func zalloc;  /* used to allocate the internal state */
    free_func  zfree;   /* used to free the internal state */
    voidpf     opaque;  /* private data object passed to zalloc and zfree */
 
    int     data_type;  /* best guess about the data type: binary or text */
    uLong   adler;      /* adler32 value of the uncompressed data */
    uLong   reserved;   /* reserved for future use */
} z_stream;    

看下兩組函數的原型:

int deflateInit (z_streamp strm, int level);  //初始化壓縮狀態,關聯相關的z_stream數據結構和壓縮比例
int deflate (z_streamp strm, int flush);   //壓縮數據,  flush表示以何種方式將壓縮的數據寫到緩衝區中。
int deflateEnd (z_streamp strm);    //壓縮結束
int inflateInit (z_streamp strm);        
int inflate (z_streamp strm, int flush);
int inflateEnd (z_streamp strm); 

關於這兩組函數的具體使用, examples目錄下有幾個具體的例子(如zpipe.c),可以直接參考。

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