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),可以直接参考。

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