`
chinamming
  • 浏览: 140997 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

zlib库剖析(1):实现概览

 
阅读更多
本文整理自zlib.net以及zlib 1.2.7的手册页http://zlib.net/manual.html。
zlib是一套免费、通用、法律上不受限制的无损数据压缩库,可以在任何硬件及操作系统上使用。zlib数据格式可以跨平台移植。不像Unix compress(1)和GIF图像格式中使用的LZW压缩方法,当前zlib中使用的压缩算法不会扩充数据(LZW在极端情况下能使文件大小变为原来2 倍或3倍)。zlib的内存印迹也独立于输入数据,并且在压缩时能够被减小。zlib由Jean-loup Gailly与Mark Adler所开发,初版0.9版在1995年5月1日发表。zlib使用抽象化的DEFLATE算法,最初是为libpng函数库所写的,后来普遍为许多软件所使用。此函数库为自由软件,使用zlib授权。
zlib授权是一个自由软件授权协议,但并非copyleft。协议原文在http://www.gzip.org/zlib /zlib_license.html。最新版本为1.2.2,2004年10月3日发布。版权持有人为Jean-loup Gailly和Mark Adler(1995-2004),类似于BSD许可。任何人都可以使用本软件,用于任何目的,包括闭源的商业应用。源码的修改和重新分发都是自由的,除了必须注明来源,并在发布的软件中保留此授权协议副本。
1、当前版本
#define ZLIB_VERSION "1.2.7"
#define ZLIB_VERNUM 0x1270
2、功能特性
zlib压缩库提供内存内压缩/解压缩函数。包括对解压数据完整性检查。这个版本只支持一种压缩方式(deflation),但是以后其他的算法也会被加入进来,并且保持同样的流接口。如果缓存区足够大,压缩被一次完成(例如输入文件被mmap了),否则就重复调用压缩。在后一种情况,程序必须在每次调用时提供更多的输入或更多输出空间。
本压缩库使用的默认压缩数据格式为zlib格式(在RFC 1950中描述),它是对deflate流(在RFC 1951中描述)的一种封装。本压缩库也支持对gzip(.gz)格式文件的读写操作,操作接口以"gz"开头,和stdio相似。gzip格式与 zlib格式不同,在RFC 1952中描述,是对deflate流的另一种封装。
本压缩库不安装任何信号处理器,解码器检查压缩数据的一致性,所以,即使在有损坏的输入情况下,本压缩库也不会崩溃。
(1)数据头
zlib能使用gzip数据头(header)、zlib数据头或者不使用数据头压缩数据。通常情况下,数据压缩使用zlib数据头,因为这提供错误数据检测。当数据不使用数据头写入时,结果是没有任何错误检测的原始DEFLATE数据,那么解压缩软件的调用者知道压缩数据在什么地方结束。
gzip数据头比zlib数据头要大,因为它保存了文件名和其他文件系统信息,事实上这是广泛使用的gzip文件的数据头格式。注意zlib函式库本身不能创建一个gzip文件,但是它能够相当轻松的通过把压缩数据写入到一个有gzip文件头的文件中。
(2)算法
目前zlib仅支持一个LZ77的变种算法,即DEFLATE的算法。这个算法使用很少的系统资源,对各种数据提供很好的压缩效果。这也是在ZIP档案中无一例外的使用这个算法。(尽管zip文件格式也支持几种其他的算法)。看起来zlib格式将不会被扩展使用任何其他算法,尽管数据头可以有这种可能性。
(3)使用资源
函式库提供了对处理器和内存使用控制的能力。不同的压缩级别数值可以指示不同的压缩执行速度。还有内存控制管理的功能。这在一些诸如嵌入式系统这样内存有限制的环境中是有用的。
(4)策略
压缩可以针对特定类型的数据进行优化。若使用者总是使用zlib压缩特定类型的数据,那么可以使用有针对性的策略可以提高压缩效率和性能。例如,如果使用者的数据包含很长的重复数据,那么可以用RLE(运行长度编码)策略,可能会有更好的结果。对于一般的数据,默认的策略是首选。
(5)错误处理
错误可以被发现和跳过,数据混乱可以被检测(只要数据和zlib或者gzip数据头一起被写入)。此外,如果全刷新点(full-flush points)被写入到压缩后的数据流中,那么错误数据是可以被跳过的,并且解压缩将重新同步到下个全刷新点(错误数据的无错恢复被提供)。全刷新点技术对于在不可靠的通道上的大数据流是很有用的,一些过去的数据丢失是不重要的(例如多媒体数据),但是建立太多的全刷新点会极大的影响速度和压缩。
(6)数据长度
对于压缩和解压缩,没有数据长度的限制。重复调用库函数允许处理无限的数据块。一些辅助代码(计数变量)可能会溢出,但是不影响实际的压缩和解压缩。当压缩一个长(无限)数据流时,最好写入全刷新点。
(7)使用zlib的软件
今天,zlib是一种事实上的业界标准,以至于在标准文档中,zlib和DEFLATE常常互换使用。数以千计的应用程序直接或间接依靠zlib压缩函式库(参考http://zlib.net/apps.html),包括:
Linux核心:使用zlib以实作网络协定的压缩、档案系统的压缩以及开机时解压缩自身的核心。
libpng,用于PNG图形格式的一个实现,对bitmap数据规定了DEFLATE作为流压缩方法。
Apache:使用zlib实作http 1.1。
OpenSSH、OpenSSL:以zlib达到最佳化加密网络传输。
FFmpeg:以zlib读写Matroska等以DEFLATE算法压缩的多媒体串流格式。
rsync:以zlib最佳化远端同步时的传输。
Subversion 、Git和 CVS等版本控制系统:使用zlib来压缩和远端仓库的通讯流量。
dpkg和RPM等包管理软件:以zlib解压缩RPM或者其他封包。
另外,zlib被用在很多其他的编程语言中。在Java中可通过java.utl.zip使用zlib库;Python中通过import zlib使用zlib库;Perl的zlib接口可在CPAN找到;Tcl的zlib接口参看http://wiki.tcl.tk/4610。因为其代码的可移植性,宽松的授权许可以及较小的内存占用,zlib在许多嵌入式设备中也有应用。

3、流数据结构

  1. typedefvoidpf(*alloc_func)OF((voidpfopaque,uIntitems,uIntsize));
  2. typedefvoid(*free_func)OF((voidpfopaque,voidpfaddress));
  3. structinternal_state;
  4. typedefstructz_stream_s{
  5. z_constBytef*next_in;/*下一个输入字节*/
  6. uIntavail_in;/*next_in中可用的字节数*/
  7. uLongtotal_in;/*目前读取的输入总字节数*/
  8. Bytef*next_out;/*下一个输出字节应该放在这*/
  9. uIntavail_out;/*next_out中剩下的可用空间*/
  10. uLongtotal_out;/*目前输出的总字节数*/
  11. z_constchar*msg;/*最后的错误消息,如果没错误为NULL*/
  12. structinternal_stateFAR*state;/*对应用程序不可见*/
  13. alloc_funczalloc;/*用来分配内部状态*/
  14. free_funczfree;/*用来释放内部状态*/
  15. voidpfopaque;/*传给zalloc和zfree的私有数据对象*/
  16. intdata_type;/*数据类型的最好猜测:二进制数据或文本*/
  17. uLongadler;/*解压数据的adler32值*/
  18. uLongreserved;/*保留为将来使用*/
  19. }z_stream;
  20. typedefz_streamFAR*z_streamp;
  21. /*来自或传给zlib例程的gzip头部信息,对这些字段的含义,参考RFC1952*/
  22. typedefstructgz_header_s{
  23. inttext;/*为true,如果压缩数据被认为是文本*/
  24. uLongtime;/*修改时间*/
  25. intxflags;/*额外标志(写gzip文件时不会用到)*/
  26. intos;/*操作系统*/
  27. Bytef*extra;/*指向额外的字段,如果没有则为Z_NULL*/
  28. uIntextra_len;/*额外字段的长度(如果extrextra!=Z_NULL则有底)*/
  29. uIntextra_max;/*extra的空间上限(只用在读头部)*/
  30. Bytef*name;/*指向以0终止的文件名,或为Z_NULL*/
  31. uIntname_max;/*name的空间上限(只用在读头部)*/
  32. Bytef*comment;/*指向以0终止的注释,或为Z_NULL*/
  33. uIntcomm_max;/*comment的空间上限(只用在读头部)*/
  34. inthcrc;/*为true,如果会有头部CRC*/
  35. intdone;/*为true,当gzip头部读取完时(写gzip文件时不会用到)*/
  36. }gz_header;
  37. typedefgz_headerFAR*gz_headerp;
当avail_in变成0时,应用程序必须更新next_int和avail_in。当avail_out变成0时,还必须更新next_out和 avail_out。应用程序在调用init函数之前必须初始化zalloc,zfree和opaque。除此,其他的所有被压缩库设置的字段都不能被应用程序修改。应用程序提供的opaque值将作为调用时传给zalloc和zfree的第一个参数,这在用户内存管理里有用。opaque值对压缩库本身并没有什么意义。如果对象没有足够的内存,zalloc必须返回Z_NULL。如果zlib被用在多线程环境中,zalloc和zfree必须是线程安全的。
在16-bit系统上,函数zalloc和zfree必须能够分配精确的65536字节,但如果定义了符号MAXSEG_64K(参看 zconf.h),则并不需要分配比这更多的空间。在MSDOS上,zalloc返回的65536字节对象的指针必须把偏移规格化为0,默认的分配函数会保证这一点(参看zutil.c)。为了减少内存需求,并且避免64K对象的分配,可以带-DMAX_WBITS=14编译参数(参看zconf.h)来编译zlib库,这样会牺牲一点压缩率。
字段total_in和total_out可用于统计和进程报告。在压缩后,total_in表示解压数据总大小,它可以被解压工具使用,特别是如果解压工具想一步之内解压所有的数据。
4、常量
  1. /*允许的flush值,更多细节参看下面的deflate()和inflate()*/
  2. #defineZ_NO_FLUSH0
  3. #defineZ_PARTIAL_FLUSH1
  4. #defineZ_SYNC_FLUSH2
  5. #defineZ_FULL_FLUSH3
  6. #defineZ_FINISH4
  7. #defineZ_BLOCK5
  8. #defineZ_TREES6
  9. /*压缩、解压函数的返回码,负数表示错误,正数表示正常事件*/
  10. #defineZ_OK0
  11. #defineZ_STREAM_END1
  12. #defineZ_NEED_DICT2
  13. #defineZ_ERRNO(-1)
  14. #defineZ_STREAM_ERROR(-2)
  15. #defineZ_DATA_ERROR(-3)
  16. #defineZ_MEM_ERROR(-4)
  17. #defineZ_BUF_ERROR(-5)
  18. #defineZ_VERSION_ERROR(-6)
  19. /*压缩级别*/
  20. #defineZ_NO_COMPRESSION0
  21. #defineZ_BEST_SPEED1
  22. #defineZ_BEST_COMPRESSION9
  23. #defineZ_DEFAULT_COMPRESSION(-1)
  24. /*压缩策略,细节参看下面的deflateInit2()*/
  25. #defineZ_FILTERED1
  26. #defineZ_HUFFMAN_ONLY2
  27. #defineZ_RLE3
  28. #defineZ_FIXED4
  29. #defineZ_DEFAULT_STRATEGY0
  30. /*data_type字段可能的值(参看inflate())*/
  31. #defineZ_BINARY0
  32. #defineZ_TEXT1
  33. #defineZ_ASCIIZ_TEXT/*为了兼容1.2.2和更早的版本*/
  34. #defineZ_UNKNOWN2
  35. /*deflate压缩方式(这个版本支持的唯一压缩方式)*/
  36. #defineZ_DEFLATED8
  37. defineZ_NULL0/*为了初始化zalloc,zfree,opaque*/
  38. /*为了兼容小于1.0.2的版本*/
  39. #definezlib_versionzlibVersion()
5、基本函数
(1)ZEXTERN const char * ZEXPORT zlibVersion OF((void));
应用程序会比较zlibVersion和ZLIB_VERSION的一致性。如果第一个字不同,说明zlib和应用程序使用的zlib.h是不一致的。这个检查将被defalteInit和infalteInit自动调用。
(2)ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
为压缩初始化内部流的状态。字段zalloc, zfree和opaque必须在调用之前初始化。如果zalloc和zfree被设为Z_NULL,deflateInit用默认分配函数来更新它们。压缩级别必须是define Z_DEFAULT_COMPRESSION,或者0到9之间,1为最快速度,9为最好的压缩率,0表示不作任何压缩(输入数据简单地被拷贝成一块)。 Z_DEFAULT_COMPRESSION为默认压缩级别,它在速度和压缩率之间取一个折衷(当前等于级别6)。函数成功时返回Z_OK,否则返回相应的错误码(Z_MEM_ERROR, Z_STREAM_ERROR或Z_VERSION_ERROR)。deflateInit不执行任何压缩动作,压缩动作由deflate()来执行。
(3)ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
压缩尽可能多的数据,直到输入缓冲区变空或输出缓冲区变满。它可能引入一些输出延迟(读取输入但不产生任何输出),除非强制刷新缓冲区。本函数执行以下一个或两个动作:
* 压缩从next_in开始的输入数据,并且更新相应的next_in和avail_in。如果不能处理所有的输入(因为输出缓冲区已满),next_in和avail_in会作相应更新,并且下一次调用deflate()时在这个点处恢复执行。
* 生成从next_out开始的输出,并且更新相应的next_out和avail_out。如果参数flush为非零,则本行为强制执行。强制频繁地刷新会降低压缩率,因此这个参数应该只在必要时才设置(在交互式应用程序中)。有些输出即使flush没有被设置也会生成。
(4)ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
所有为当前流分配的动态数据结构被释放。本函数抛弃任何未处理的输入,并且不会刷新任何挂起的输出。成功时返回Z_OK,流状态不一致时返回 Z_STREAM_ERROR,流过早被释放时(一些输入或输出被抛弃了)返回Z_DATA_ERROR。在错误情形中,msg信息可能被设置,然后指向一个静态字符串。
(5)ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
为解压初始化内部流状态。字段next_in, avail_in, zalloc, zfree和opaque必须在调用之前初始化。如果next_in不等于Z_NULL且avail_in足够大(准确的值取决于压缩方式),inflateInit从zlib头部确定压缩方式,然后分配所有数据结构。否则分配将会被推迟到第一次调用inflate。如果zalloc和 zfree被设为Z_NULL,inflateInit用默认分配函数来更新它们。函数返回 Z_OK,Z_MEM_ERROR,Z_VERSION_ERROR或Z_STREAM_ERROR。
(6)ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
解压尽可能多的数据。直到输入缓冲区变空或输出缓冲区变满。它可能引入一些输出延迟(读取输入但不产生任何输出),除非强制刷新缓冲区。本函数执行以下一个或两个动作:
* 解压从next_in开始的输入数据,并且更新相应的next_in和avail_in。如果不能处理所有的输入(因为输出缓冲区已满),next_in会作相应更新,并且下一次调用inflate()时在这个点处恢复执行。
* 生成从next_out开始的输出,并且更新相应的next_out和avail_out。inflate()生成尽可能多的输出,直到没有更多的输入或者输出缓冲区已满。flush参数可以是Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,Z_BLOCK或Z_TREES。
(7)ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
所有为这个stream动态分派的数据结构在这被释放。 这个函数丢弃所有未处理的输入,并且不会刷新任何挂起的输出。如果成功,inflateEnd返回Z_OK;如果stream是不一致的,返回 Z_STREAM_ERROR,在错误情形中,msg信息可能被设置,然后指向一个静态字符串。
6、高级函数
以下函数用于一些特殊的应用中:
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy));
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength));
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source));
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy));
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain));
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen));
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, unsigned *pending, int *bits));
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value));
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head));

ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits));
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength));
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, z_streamp source));
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, int windowBits));
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int bits, int value));
ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head));
ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, unsigned char FAR *window));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc));
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
7、实用函数
以下实用函数的实现建立在前面介绍的基本面向流的函数上。为了简化接口,设置了一些默认选项(压缩级别,内存使用,标准内存分配器功能)这些实用函数的源代码很容易被修改,如果你要实现一些特殊选项。
(1)ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
压缩source buffer到destination buffer。sourceLen是source buffer的长度(byte)。调用前,destLen是destination buffer的总共长度(byte),它必须至少是compressBound(sourceLen)的返回值,一般为sourceLen长度的0.1% 再加上12个byte。退出前,destLen是实际的compressed buffer长度。如果输入文件是mmap的,这个函数可以一次压缩整个文件。如果压缩成功返回Z_OK, 如果没有足够的内存返回Z_MEM_ERROR,如果输出缓冲区中没有足够的空间返回Z_BUF_ERROR。
(2)ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level));
与compress功能一样,只不过多了一个level参数。参数level为压缩级别,与defalteInit中的含义一样。如果level是无效的,返回Z_STREAM_ERROR。
(3)ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
返回compressed size的上限,在sourceLen个字节上执行copress()或compress2()后。在调用compress()或compress2() 分配destination buffer之前,本函数可用于计算的destLen。
(4)ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
解压source buffer到destination buffer。sourceLen是source buffer的长度(byte)。调用前,destLen是destination buffer的总共长度(byte),它必须足够大以容纳全部解压后的数据(解压后的数据大小必须在先前由压缩工具保存好,然后通过一些机制传给解压工具,这种机制不在本压缩库的讨论范围内)。退出前,destLen是实际的compressed buffer长度。如果输入文件是mmap的,这个函数可以一次解压整个文件。如果解压成功返回Z_OK,如果没有足够的内存返回 Z_MEM_ERROR,如果输出缓冲区中没有足够的空间返回Z_BUF_ERROR,如果输入数据有损坏返回Z_DATA_ERROR。在没有足够空间的情况下,uncompress()用解压数据填充输出缓冲区,直到空间末尾为上。
(5)下面是gzip文件访问函数。
typedef struct gzFile_s *gzFile; /* 半透明的gzip文件描述符 */
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
打开一个gzip(.gz)文件进行读/写。mode参数和fopen一样("rb"或" wb"),但也可以包括压缩级别如"wb9";或者一个策略,如"f"作为过滤数据"wb6f","h"是huffman压缩"wb1h","R"是行程编码"wb1R",
"F"是固定编码压缩"wb9F"(关于压缩策略可参看deflateInit2的描述);如果mode为"T",将指定透明的写或附加操作,没有压缩,也不使用gzip格式。可见gzopen可用于读一个没有gzip格式的文件,这时gzread
直接从没有解压缩的文件中读数据。如果文件不能被打开或是没有足够的内存,gzopen将返回NULL。
ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
用文件描述符来关联一个gzFile。文件描述符可通过open, dup, creat, pipe或fileno(如果文件之前已经用open打开了)之类的调用获取。mode参数与gzopen中类似。
ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
设置本函数库用到内部缓冲区大小。默认大小为8192字节。本函数必须在gopen或gzdopen之后调用,在任何读或写文件之前调用,缓冲区内存分配总是会被推迟第一次读或写文件时。两个缓冲区被分配,要么两个缓冲区都使用这个设置值 ,要么一个使用这个设置值,另一个为这个值的两倍。一个更大的缓冲区大小,如64K或128K字节,将显著加快解压速度(读速度)。gzbuffer成功返回0,失败返回-1,例如调用得太晚。
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
动态更新压缩级别或策略。参数含义参看deflateInit2的描述。成功返回Z_OK,如果文件没有为写操作而打开,返回Z_STREAM_ERROR。
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
从压缩文件中读取给定大小的解压字节数。如果输入文件不是gzip格式,gzread直接复制指定定大小的字节数到缓冲区。返回实际读取的字节数,出错则返回-1。
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
写入给定大小的未解压数据到压缩文件中,返回实际写入的字节数,出错返回0。
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
在格式字符串的控制下转换、格式化或写入参数到压缩文件,这类似于fprintf。返回实际写入的字节数,出错则返回0。
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
写入给定的以null终止的字符串到压缩文件,写入时不包括末尾的null字符。返回实际写入的字符数,出错时返回-1。
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
从压缩文件中读取字节,直到len-1个字符被读取,或者一个换行字符被读取并传给buf,或者一个end-of-file条件被触发。如果各字符都读取完或者len==1,字符串最后将加上null字符。返回buf,如果出错则返回Z_NULL。
ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
写入一个被转换成unsigned char的字符c到压缩文件,返回写入的字符,出错则返回-1。
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
从压缩文件中读取一个字节,返回这个字节。如果出错或文件到达末尾,返回-1。本函数实现为一个宏,以加快速度。
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
推回一个字符到原来的流中,这个字符即将在下一次读操作中作为首个被读取的字符。返回这个字符,出错则返回-1。
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
刷新所有挂起的输出到压缩文件。参数flush与deflate()中类似。返回值为zlib错误码(参看gzerror函数)。
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence));
设置压缩文件下一次gzread或gzwrite操作的开始位置。
ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
重绕给定的文件,本函数只用于读操作,等价于(int)gzseek(file, 0L, SEEK_SET)。
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
如果end-of-file指示符被设置,返回true(1),否则返回0。
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
如果读取时内容被直接拷贝到缓冲区,返回1,否则返回0。
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
刷新所有挂起的输出,关闭压缩文件,释放所有的(de)compression状态。注意一旦文件被关闭,不能再调用gzerror,因为所有结构都被释放。在一个文件上不能调用gzclose多次,因为在一次分配上释放操作不能被调用多次。
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
返回在给定的压缩文件上发生的最后一次错误消息。
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
清除给定压缩文件的错误消息和end-of-file标志。
8、校验函数
这些函数和压缩是没有关系的,但是被公开是因为在应用序使用本压缩库时,他们可能是有用的。
(1)ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
用字节buf[0...len-1]更新一个运行的Adler-32校验和,返回这个新的CRC-32。如果buf为NULL,返回这个校验和需要的初始值。一个Adler-32校验和作为CRC32几乎是可靠的,但是计算起来更快。使用例子:

  1. uLongadler=adler32(0L,Z_NULL,0);
  2. while(read_buffer(buffer,length)!=EOF){
  3. adler=adler32(adler,buffer,length);
  4. }
  5. if(adler!=original_adler)error();
(2)ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
用字节buf[0...len-1]更新一个运行的CRC-32校验和,返回这个新的校验和。如果buf为NULL,返回这个CRC需要的初始值。使用例子:
  1. uLongcrc=crc32(0L,Z_NULL,0);
  2. while(read_buffer(buffer,length)!=EOF){
  3. crc=crc32(crc,buffer,length);
  4. }
  5. if(crc!=original_crc)error();
9、文件概览
alder32.c:计算数据流的Alder-32校验和,实现alder32()。
crc32.h和crc32.c:计算数据流的CRC-32,实现crc32()。
deflate.h和deflate.c:使用默认算法压缩数据,实现deflate函数簇。
inflate.h和inflate.c:zlib的解压,实现inflate函数簇。
compress.c:实现内存缓冲区的压缩,包括compress(), compress2(), compressBound()。
uncompr.c:实现内存缓冲区的解压,包括uncompress()。
gzguts.h和gzlib.c:读写gzip文件的通用实现,包括gzopen(), gzdopen(), gzbuffer(), gzrewind(), gzseek(), gztell(), gzoffset(), gzeof(), gzerror(), gzclearerr()。
gzclose.c:实现gzclose()。
gzread.c:读取gzip文件的实现,包括gzread(), gzgetc(), gzungetc(), gzgets(), gzdirect(), gzclose_r()。
gzwrite.c:写gzip文件的实现,包括gzwrite(), gzputc(), gzputs(), gzprintf(), gzflush(), gzsetparams(), gzclose_w()。
infback.c:使用回调接口实现解压,包括inflateBackInit(), inflateBack(), inflateBackEnd()。
zutil.h和zutil.c:zlib库用到的工具函数。包括zlibVersion(), zlibCompileFlags(), zError()。
zlib.h:zlib库导出的接口描述文件,应用程序使用zlib库时需要本文件。
zconf.h:zlib库的编译配置文件,如果编译时需要给所有库函数加上唯一的前缀,或者需要针对不同平台作特殊编译,需要用到本文件。还包括标准 C/C++兼容性定义;编译成DLL时是否使用WINAPI/WINAPIV调用方式;类型定义Byte,uInt, uLong, voidpf等。
inftrees.h和inftrees.c:为有效的解码生成Huffman树。
trees.h和trees.c:使用Huffman编码输出压缩的数据。
inffixed.h:使用固定编码压缩。
inffast.h和inffast.c:快速解压数据。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics