C/C++编程:zlib手册翻译

1059 篇文章 290 订阅

版本

#define ZLIB_VERSION "1.2.11"
#define ZLIB_VERNUM 0x12b0

测试

#include <stdio.h>
#include <zlib.h>


int main(void)
{
    printf("ZLIB_VERSION = %s\n", ZLIB_VERSION);
    printf("ZLIB_VERNUM = %d", ZLIB_VERNUM);
    return 0;
}

介绍

zlib压缩库提供内存中的压缩和解压算法,包括未压缩数据的完整性检查。这个版本的库只支持一种压缩方法 (deflation),但是以后会添加其他方法,并具有相同的流接口。

如果缓冲区足够大(例如,如果输入文件是mmap),压缩可以在单个步骤中完成,也可以通过重复调用压缩函数来完成。在后一种情况下,应用程序必须在每次调用之前提供更多的输入/提供更多的输出空间。

内存函数默认使用的压缩数据格式是zlib格式,这是RFC 1950中记录的一个zlib包装器,围绕着一个deflate流,这个deflate流本身也记录在RFC 1951中。

该库还支持读写gzip (.gz)格式的文件,其接口类似于使用以"gz"开头的函数的stdio。gzip格式与zlib格式不同。gzip是一个gzip包装器,在RFC 1952中记录,围绕一个deflate流。

这个库也可以在内存中读写gzip和raw deflate流。

zlib格式被设计为紧凑和快速,以便在内存和通信信道上使用。gzip格式是为文件系统上的单文件压缩而设计的,它有一个比zlib更大的头文件来维护目录信息,并且使用一种不同的,比zlib更慢的检查方法。

库不安装任何信号处理程序。解码器会检查压缩数据的一致性,因此即使在输入损坏的情况下,库也不会崩溃。

流数据结构

typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
typedef void   (*free_func)  OF((voidpf opaque, voidpf address));

struct internal_state;

typedef struct z_stream_s {
    z_const Bytef *next_in;     /* 下一个输入字节 */
    uInt     avail_in;  /* 可用的字节数 */
    uLong    total_in;  /* 到目前为止读取的输入字节总数 */

    Bytef    *next_out; /* 下一个输出字节将放在这里 */
    uInt     avail_out; /* next_out 剩余可用空间 */
    uLong    total_out; /*  到目前为止输出的总字节数 */

    z_const char *msg;  /*  最后一条错误信息,如果没有错误则为 NULL */
    struct internal_state FAR *state; /* 应用程序不可见 */

    alloc_func zalloc;  /* 用于分配内部状态 */
    free_func  zfree;   /* 用于释放内部状态 */
    voidpf     opaque;  /* 传递给 zalloc 和 zfree 的私有数据对象 */

    int     data_type;  /* best guess about the data type: binary or text
                           for deflate, or the decoding state for inflate */
    uLong   adler;      /* 未压缩数据的 Adler-32 或 CRC-32 值 */
    uLong   reserved;   /* 留作将来使用 */
} z_stream;

typedef z_stream FAR *z_streamp;

传入和传出zlib例程的gzip头信息。有关这些字段含义的更多详细信息,请参阅 RFC 1952。

typedef struct gz_header_s {
    int     text;       /* 如果压缩数据被认为是文本,则为真 */
    uLong   time;       /* 修改时间 */
    int     xflags;     /* 额外的标志(在编写 gzip 文件时不使用) */
    int     os;         /* 操作系统 */
    Bytef   *extra;     /* 指向额外字段的指针,如果没有,则指向Z_NULL */
    uInt    extra_len;  /* 额外的字段长度(如果extra != Z_NULL), 则有效 */
    uInt    extra_max;  /* 额外的空格(仅在读取header时) */
    Bytef   *name;      /* 指向以零结尾的文件名或Z_NULL的指针 */
    uInt    name_max;   /* 名称处的空格(仅在读取header时) */
    Bytef   *comment;   /* 指向以零结尾的注释或Z_NULL的指针 */
    uInt    comm_max;   /* 注释处的空格(仅在读取header时) */
    int     hcrc;       /* 如果存在或将存在标头crc,则为true */
    int     done;       /* 当读取gzip头完成时为true(写入gzip文件时不使用) */
} gz_header;

typedef gz_header FAR *gz_headerp;

结构的使用

  • 当avail_ in降为零时,应用程序必须更新next_ in和avail_ in。
  • 当avail_ out降为0时,应用程序必须更新next_ out和avail_ out。
  • 应用程序必须在调用init函数之前初始化zalloc、zfree和opaque。

应用程序提供的opaque值将作为调用zalloc和zfree的第一个参数传递。这对于自定义内存管理非常有用。压缩库对opaque值没有附加任何意义。

  • 所有其他字段由压缩库设置,不得由应用程序更新。

  • 如果没有足够的内存存放对象,zalloc必须返回Z_ NULL。
  • 如果在多线程应用程序中使用zlib,那么zalloc和zfree必须是线程安全的。在这种情况下,zlib是线程安全的。
  • 当zalloc和zfree在进入初始化函数时为Z_ NULL时,它们被设置为使用标准库函数malloc()和free()的内部例程。
  • 在16位系统上,函数zalloc和zfree必须能够精确地分配65536字节,但如果定义了符号MAXSEG_ 64K(参见zconf.h),则不需要分配更多的字节。

警告:

  • 在MSDOS上,zalloc返回的对象正好65536字节的指针必须将偏移量归零。
  • 这个库提供的默认分配函数确保了这一点(请参阅zutil.c)。
  • 为了减少内存需求并避免任何64K对象的分配,以牺牲压缩比为代价,使用- dmax_wbits =14(参见zconf.h)编译库。

  • 字段total_ in和total_ out可用于统计或进度报告。
  • 压缩后,total_ in保存了未压缩数据的总大小,可以保存下来供解压缩程序使用(特别是当解压缩程序想要在一个步骤中解压缩所有数据时)。

常数

允许flush值,具体参见下面的deflate()inflate()

#define Z_NO_FLUSH      0
#define Z_PARTIAL_FLUSH 1
#define Z_SYNC_FLUSH    2
#define Z_FULL_FLUSH    3
#define Z_FINISH        4
#define Z_BLOCK         5
#define Z_TREES         6

压缩/解压缩函数的返回代码。负值是错误,正值用于特殊但正常的事件:

#define Z_OK 0
#define Z_STREAM_END 1
#define Z_NEED_DICT 2
#define Z_ERRNO (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR (-3)
#define Z_MEM_ERROR (-4)
#define Z_BUF_ERROR (-5)
#define Z_VERSION_ERROR (-6)

压缩级别:

#define Z_NO_COMPRESSION 0
#define Z_BEST_SPEED 1
#define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_COMPRESSION (-1)

压缩策略——详见下面的deflateInit2():

#define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
#define Z_FIXED 4
#define Z_DEFAULT_STRATEGY 0

deflate() 的data_type字段的可能值:

#define Z_BINARY 0
#define Z_TEXT 1
#define Z_ASCII Z_TEXT /* 与 1.2.2 及更早版本兼容 */
#define Z_UNKNOWN 2

deflate 的压缩方法(在此版本支持的唯一一个):

#define Z_DEFLATED 8

用于初始化zalloc、zfree、opaque:

#define Z_NULL 0

与版本 < 1.0.2 兼容:

#define zlib_version zlibVersion()

基本功能

ZEXTERN const char * ZEXPORT zlibVersion OF((void));
  • 应用程序可以比较zlibVersion和ZLIB_VERSION的一致性。
  • 如果第一个字符不同,则实际使用的库代码与应用程序使用的zlib.h头文件不兼容。
  • 此检查由deflateInit和inflateInit自动进行。
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
  • 初始化用于压缩的内部流状态。

    • 字段 zalloc、zfree和opaque必须在调用deflateInit 之前初始化。
    • 如果zalloc和zfree设置为Z_NULL,deflateInit更新它们以使用默认分配函数。
  • 压缩级别必须为Z_DEFAULT_COMPRESSION,或介于 0 和 9 之间:

    • 1 表示最佳速度,9 表示最佳压缩,0 表示根本不压缩(输入数据一次只复制一个块)
    • Z_DEFAULT_COMPRESSION请求速度和压缩之间的默认折衷(当前相当于级别 6)。
  • 如果成功,deflateInit将返回Z_OK;

    • 如果内存不足,则返回Z_MEM_ERROR;
    • 如果级别不是有效的压缩级别,则返回Z_STREAM_ERROR;
    • 如果zlib库版本(zlib_Uversion)与调用方假定的版本(zlib_Uversion)不兼容,则返回Z_ VERSION_ ERROR。
    • 如果没有错误消息,则msg设置为null。
  • deflateInit不执行任何压缩:这将由deflate()完成。

在这里插入图片描述

ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
  • deflate压缩尽可能多的数据,并在输入缓冲区变空或输出缓冲区变满时停止。它可能会引入一些输出延迟(读取输入而不产生任何输出),强制刷新时除外。
  • 详细的语义如下所示。deflate执行以下一个或两个操作:
    • 从next_in开始压缩更多输入并相应地更新next_in和avail_in 。如果不能处理所有输入(因为输出缓冲区中没有足够的空间),则会更新next_in和Avail_in并且此时将继续处理以供下一次调用deflate()
    • 从next_out开始生成更多输出,并相应地更新next_out和avail_out 。如果参数flush不为零,则强制执行此操作。强制刷新经常会降低压缩率,因此仅在必要时才设置此参数。即使flush为零,也可能提供一些输出

  • 在调用deflate()之前,应用程序应该通过提供更多的输入和/或消费更多的输出,并相应地更新avail_ in或avail_out,确保至少有一个操作是可能的;
  • 在调用之前,avail_out不应该为零。
  • 应用程序可以在需要的时候使用压缩的输出,例如当输出缓冲区已满时(avail_out == 0),或者在每次调用deflate()之后。
  • 如果deflate返回Z_OK并且avail_out为零,则必须在缓冲区腾出空间后再次调用它,因为可能会有更多的输出挂起。请参阅deflatePending(),如果需要,可以使用它来确定在这种情况下是否有更多输出。

  • 通常,flush参数设置为Z_NO_FLUSH,这允许deflate决定在产生输出之前累积多少数据,以最大化压缩。

高级功能

以下功能仅在某些特殊应用中需要。

ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
                                     int  level,
                                     int  method,
                                     int  windowBits,
                                     int  memLevel,
                                     int  strategy));
  • 这是带有更多压缩选项的另一个版本的deflateInit。调用者必须先初始化next_ in、zalloc、zfree和opaque字段。

  • method参数为压缩方法。在这个版本的库中,它必须是Z_ DEFLATED。

  • windowBits 参数参数是窗口大小(历史缓冲区大小)的以二为底的对数。

    • 对于这个版本的库,它应该在8到15之间。
    • 此参数的值越大,压缩效果越好,但会牺牲内存使用率。
    • 如果改用deflateInit,则默认值为15。
  • memLevel参数指定应该为内部压缩状态分配多少内存。

    • memLevel=1使用最小内存,但速度较慢,并降低了压缩比;
    • memLevel=9使用最大内存以获得最佳速度。
    • 缺省值为8。
    • 关于windowBits和memLevel的总内存使用量,请参阅zconf.h。
  • strategy 参数用于优化压缩算法

    • 使用值Z_ DEFAULT_ STRATEGY用于普通数据
    • 使用值Z_ FILTERED用于过滤器(或预测器)产生的数据
    • 使用值Z_ HUFFMAN_ ONLY强制霍夫曼编码(没有字符串匹配)
    • Z_ RLE限制匹配距离为一个(行程长度编码)
  • 如果成功,deflateInit2将返回Z_OK;

    • 如果内存不足,则返回Z_MEM_ERROR;
    • 如果参数无效(例如无效方法),则返回Z_STREAM_ERROR;
    • 如果zlib库版本(zlib_版本)与调用方假定的版本(zlib_版本)不兼容,则返回Z_VERSION_ERROR。
    • 如果没有错误消息,则msg设置为null。
    • deflateInit2不执行任何压缩:这将由deflate()完成。

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值