https://www.zlib.net/manual.html
1.2.11版相对于1.2.10具有以下关键改进:
- 修复从窗口拉出最后一个块时缩小存储的错误
- 允许立即进行deflateParams更改,然后再进行任何deflate输入
由于错误修复,任何1.2.9或1.2.10的安装应立即替换为1.2.11。
1.2.10版对1.2.9进行了以下关键改进:
- 修复deflate_stored()中零长度输入的错误
- 修复gzwrite.c中产生损坏的gzip文件的错误
1.2.9版对1.2.8进行了以下主要改进:
- 改进compress()和uncompress()以支持大长度
- 允许在源目录之外构建zlib
- 修复0级与Z_HUFFMAN或Z_RLE一起使用时的错误
- 修复创建非常大的gzip标头中的错误
- 添加uncompress2()函数,该函数返回使用的输入大小
- 显着加快0级放气(存储)
- 添加gzfread()和gzfwrite(),复制fread()和fwrite() 的接口
- 添加具有size_t长度的 crc32_z()和adler32_z()函数
- 许多可移植性改进
zlib被设计为一个免费的,通用的,法律上不受限制的-即不受任何专利保护的无损数据压缩库,几乎可以在任何计算机硬件和操作系统上使用。zlib数据格式本身可跨平台移植。与Unix compress(1)和GIF图像格式中使用的LZW压缩方法不同,zlib中当前使用的压缩方法实际上从不扩展数据。(在极端情况下,LZW可以使文件大小增加一倍或三倍。)zlib的内存占用空间也独立于输入数据,并且可以在必要时减少压缩量,从而减少了它。关于这两点的更精确的技术讨论,请参见 另一页。
zlib由Jean-loup Gailly(压缩)和Mark Adler (解压缩) 编写 。Jean-loup还是gzip(1)的主要作者, comp.compression FAQ列表的作者,也是 Info-ZIP的Zip的前维护者;Mark还是gzip和 UnZip的主要解压缩例程的作者,并且是Zip的原始作者。毫不奇怪,zlib中使用的压缩算法与gzip和Zip中使用的压缩算法本质上是相同的,即起源于PKWARE的PKZIP 2.x的“放气”方法 。
可以通过发送电子邮件至Mark和Jean-loup zlib@gzip.org 。在寻求帮助之前,请阅读常见问题解答和手册。我们遇到了太多的问题,而zlib文档中已经有了答案。
deflate和zlib规范都在1996年5月获得了正式的Internet RFC状态,并且zlib本身在Java开发工具包(JDK)的1.1版中被用作 原始类和JAR存档格式的组成部分。
上面可爱的zlib-vise图片由Dobb博士杂志的艺术总监Bruce Gardner提供。它出现在1997年1月号的Mark Nelson的文章中(请参阅下文)。
内容
- 序幕
- 版
- 介绍
- 流数据结构
- 结构用法
- 常数
- 基本功能
- 进阶功能
- 实用功能
- gzip文件访问功能
- 校验和功能
- 未记录的功能
序幕
zlib通用压缩库
版本1.2.11,2017年1月15日
版权所有(C)1995-2017 Jean-loup Gailly和Mark Adler
该软件按“原样”提供,没有任何明示或暗示的保证。作者概不对使用此软件引起的任何损失负责。
任何人均有权将本软件用于任何目的(包括商业应用程序),并可以对其进行更改和自由分发,但要遵守以下限制:
- 此软件的来源不得虚假陈述;您不得声称自己编写了原始软件。如果您在产品中使用该软件,则应感谢产品文档中的确认,但这不是必需的。
- 更改后的源版本必须清楚地标上原样,并且不得将其误认为是原始软件。
- 不得从任何源分发中删除或更改此通知。
让·卢普·盖伊·马克·阿德勒
zlib库 使用的数据格式由RFC(请求注释)1950年至1952年在文件 rfc1950(zlib格式), rfc1951(放气格式)和 rfc1952(gzip格式)中描述。
介绍
的ZLIB压缩库提供的内存中的压缩和解压功能,包括未压缩数据的完整性检查。该版本的库仅支持一种压缩方法(放气),但其他算法将在以后添加,并具有相同的流接口。
如果缓冲区足够大(例如,如果对输入文件进行了map'ed操作),则压缩可以在单个步骤中完成,也可以通过重复调用压缩函数来完成。在后一种情况下,应用程序必须在每次调用之前提供更多的输入和/或使用输出(提供更多的输出空间)。
内存功能默认使用的压缩数据格式是zlib格式,它是RFC 1950中记录的zlib包装器,包裹在deflate流中,而deflate流本身在RFC 1951中记录了。
该库还支持以gzip(.gz)格式读取和写入文件,其接口类似于使用“ gz”开头的功能的stdio接口。该gzip的格式是从不同的zlib格式。 gzip是 gzip包装器,在RFC 1952中有说明,包裹在deflate流中。
该库还可以选择在内存中读写gzip和原始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; /* 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 will go here */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 textfor deflate, or the decoding state for inflate */uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */uLong reserved; /* reserved for future use */
} z_stream;typedef z_stream FAR *z_streamp;
与zlib例程之间传递的gzip标头信息。有关这些字段含义的更多详细信息,请参见RFC 1952。
typedef struct gz_header_s {int text; /* true if compressed data believed to be text */uLong time; /* modification time */int xflags; /* extra flags (not used when writing a gzip file) */int os; /* operating system */Bytef *extra; /* pointer to extra field or Z_NULL if none */uInt extra_len; /* extra field length (valid if extra != Z_NULL) */uInt extra_max; /* space at extra (only when reading header) */Bytef *name; /* pointer to zero-terminated file name or Z_NULL */uInt name_max; /* space at name (only when reading header) */Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */uInt comm_max; /* space at comment (only when reading header) */int hcrc; /* true if there was or will be a header crc */int done; /* true when done reading gzip header (not usedwhen writing a gzip file) */
} gz_header;typedef gz_header FAR *gz_headerp;
结构用法
当avail_in降至零时 ,应用程序必须更新next_in和avail_in。当avail_out 降至零时,它必须更新next_out和avail_out。在调用init函数之前,应用程序必须初始化zalloc,zfree和 opaque。所有其他字段由压缩库设置,并且不得由应用程序更新。
应用程序提供 的不透明值将作为调用zalloc和zfree的第一个参数传递。这对于自定义内存管理很有用。压缩库对不透明值没有任何意义 。
如果对象没有足够的内存,则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保留未压缩数据的总大小,并可以保存以供解压缩器使用(特别是如果解压缩器要在单个步骤中解压缩所有内容)。
常数
允许的刷新值;有关详细信息,请参见下面的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 /* for compatibility with 1.2.2 and earlier */
#define Z_UNKNOWN 2
该放气的压缩方法(在此版本支持的唯一一个)。
#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。如果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如果水平是不是有效的压缩级别, Z_VERSION_ERROR如果zlib的库版本(zlib_version)是不兼容的版本假设由主叫方(ZLIB_VERSION)。 如果没有错误消息,则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)时,或在每次调用latelate ()之后。如果放气的回报Z_OK 和零avail_out,它必须再次在缓冲腾出空间后调用,因为可能有更多的输出悬而未决。看到deflatePending(),如果需要,可以使用它来确定在这种情况下是否有更多的输出。
通常,参数flush设置为Z_NO_FLUSH,它允许放气决定在产生输出之前要累积多少数据,以使压缩最大化。
如果参数flush设置为Z_SYNC_FLUSH,则所有未决的输出都将刷新到输出缓冲区,并且输出在字节边界上对齐,以便解压缩器可以获取到目前为止可用的所有输入数据。(特别 是如果在调用之前提供了足够的输出空间,则调用之后avail_in为零。)刷新可能会降低某些压缩算法的压缩率,因此应仅在必要时使用它。这样就完成了当前的deflate块,并在其后跟随着一个空的存储块,该块是三位加下一个字节的填充位,后跟四个字节(00 00 ff ff)。
如果将flush设置为Z_PARTIAL_FLUSH,则所有未决的输出都将刷新到输出缓冲区,但是输出未与字节边界对齐。到目前为止,所有输入数据都可用于解压缩器,就像Z_SYNC_FLUSH一样。这将完成当前的deflate块,并在其后跟随一个10位长的空固定代码块。这样可以确保输出足够的字节,以便解压缩器在空的固定代码块之前完成该块。
如果将flush设置为Z_BLOCK,则就像Z_SYNC_FLUSH一样,完成并发出一个放气块,但输出未在字节边界上对齐,并且当前块的最多7位被保留为在写后的下一个字节。下一个放气块完成。在这种情况下,此时可能无法为解压缩器提供足够的位,以完成对到目前为止提供给压缩器的数据的解压缩。它可能需要等待下一个块被发出。这适用于需要控制放气块发射的高级应用。
如果冲洗设定为Z_FULL_FLUSH,所有的输出被冲洗与 Z_SYNC_FLUSH,并且压缩状态复位,以便解压缩可以从这个点以前,如果压缩后的数据已被破坏,或者如果随机存取需要重新启动。过多使用Z_FULL_FLUSH会严重降低压缩率。
如果deflate返回avail_out == 0,则必须使用相同的flush参数值和更多输出空间(更新的 avail_out)再次调用此函数,直到刷新完成(deflate返回非零的 avail_out)。对于Z_FULL_FLUSH或Z_SYNC_FLUSH,请确保 avail_out大于六,以避免由于返回时avail_out == 0而导致重复的刷新标记 。
如果参数flush设置为Z_FINISH,则处理未决的输入,刷新未决的输出,如果有足够的输出空间,则deflate返回Z_STREAM_END。如果deflate使用Z_OK或Z_BUF_ERROR返回,则必须使用Z_FINISH和更多的输出空间(更新的 avail_out)再次调用此函数,但不能再输入任何数据,直到它以Z_STREAM_END或错误返回。后放气已经恢复Z_STREAM_END,上清溪的唯一可能的操作是deflateReset或deflateEnd。
Z_FINISH可以在第一被用于放气后调用deflateInit如果全部压缩在一个单一步骤中完成。为了完成一次调用,avail_out必须至少是deflateBound返回的值(请参见下文)。然后保证deflate返回Z_STREAM_END。如果没有足够的输出空间,则deflate不会返回Z_STREAM_END,并且必须如上所述再次调用它。
deflate()将strm-> adler设置为到目前为止已读取的所有输入的Adler-32校验和(即total_in字节)。如果正在生成gzip流,则 strm-> adler将是到目前为止读取的输入的CRC-32校验和。(请参阅 下面的deflateInit2。)
如果deflate()可以很好地猜测输入数据类型(Z_BINARY或Z_TEXT),则可以更新strm-> data_type。如果有疑问,则将数据视为二进制。该字段仅用于提供信息,不会以任何方式影响压缩算法。
deflate()返回Z_OK(如果已取得一些进展(处理了更多输入或产生了更多输出)),Z_STREAM_END(如果已消耗所有输入并且产生了所有输出(仅当flush设置为 Z_FINISH时)),Z_STREAM_ERROR(如果流状态为不一致(例如,如果next_in或next_out为Z_NULL或应用程序无意中写入了状态),或者如果无法进行升级,则为Z_BUF_ERROR(例如 avail_in或avail_out为零)。注意Z_BUF_ERROR不是致命的,并且 deflate() 可以用更多的输入和更多的输出空间再次调用以继续压缩。