版本
#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()完成。