zlib.h介绍--关于deflate函数和inflate函数

http://blog.csdn.net/code_bomber/article/details/1736450


关于deflate函数和inflate函数

/*
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)。

     函数成功返回Z_OK,如果没有足够的内存则返回Z_MEM_ERROR,如果不是一个有效的压缩级别则

返回Z_STREAM_ERROR,版本不兼容则返回Z_VERSION_ERROR。如果没有错误信息则msg被设置为0。

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参数不是为0的化这个动作是

强制性的,经常性的强制刷新缓冲区会降低压缩比率,所以只有必要的时候才会设置这个参数(在交际程

序时),一些数据也会输出即使刷新没有被设置。

 

在调用deflate()函数之前,应用程序必须保证至少上面的一个动作被执行,用提供更多输入数据和/或消耗更多

输出数据的方式.,从而更新avail_in或avail_out;avail_out在函数调用之前千万不能为0。应用程序可以随时

消耗被压缩的输出数据,举个例子:当输出缓冲满了或者在每次调用deflate()之后,如果deflate返回Z_OK

并avail_out为0时,deflate()必须再次被调用。

 

一般刷新参数要设置为Z_NO_FLUSH,它允许deflate决定在产生输出时会积聚多少数据,为了使压缩最大化

 

如果flush参数被设置为Z_SYNC_FLUSH,所有的未处理的输出都会被传输到输出缓冲,缓冲区会按字节边界

排列,所以压缩器可以获得目前为止所有有效的数据。(特别的在调用函数后avail_in为0,如果在调用之前

有足够的输出空间)。由于一些压缩策略,刷新也许会退化压缩,所以只有必要的时候才会用。

 

如果刷新参数被设置为Z_FULL_FLUSH,所有输出会被刷新就像使用Z_SYNC_FLUSH一样,刷新状态会

复位,如此以致于如果之前的已压缩数据被毁坏或涉及了随机存取,解压可以重新开始。

 

如果deflate返回avail_out==0,这个函数必须再次被调用,刷新参数要相同,扩大输出空间(更新的

avail_out),直到完全刷新(deflate返回非0的avail_out)。在Z_FULL_FLUSH或Z_SYNC_FLUSH的

情况下,要确保avail_out要比6更大从而避免重复的刷新依赖于avail_out==0的返回值。

 

如果刷新参数设置为Z_FINISH,未处理的输入被处理完毕,未处理的输出被刷新并且deflate返回Z_STREAM_END

如果有足够的输出空间;如果deflate返回Z_OK,此函数必须再次被调用用Z_FINISH和更多的输出空间而不

用更多的输入数据,直到它返回Z_STREAM_END或一个error。在deflate返回Z_STREAM_END后,可以

执行的操作就只有deflateReset或deflateEnd。

 

如果所有压缩操作在一步完成,deflateInit之后Z_FINISH可以立即被使用。在这种情况下,avail_out

至少是deflateBound的返回值。如果deflate不返回Z_STREAM_END,它就得被再次调用。

 

deflate()把adler32设置为strm->adler来检查目前为止所有输入

 

如果deflate可以对输入数据类型(Z_BINARY或Z_TEXT)做一个好的猜测,它可能会更新strm->data_type。

不确信的是,这些数据被认为是二进制的,这些字段仅仅是些信息而不会影响压缩算法

 

如果做了一些改进(更多的输入或更多的输出产生)deflate()返回Z_OK,如果所有输入被消耗以及所有输出

都产生(仅仅在flush被设置为Z_FINISH时),返回Z_STREAM_END,如果流状态不一致(next_in或

next_out为NULL)返回Z_STREAM_ERROR,如果程序都不能进行(next_in或next_out为0)返回

Z_BUF_ERROR。注意Z_BUF_ERROR不是致命的,deflate可以被再次调用with更多的input和output空间

这样可以继续执行压缩。

*/ 

 ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
/*为这个流分配的所有动态的数据结构都会被释放,这个函数丢弃了没有处理的输入数据而且不刷新未处理

的输出缓冲区。

deflateEnd返回Z_OK如果成功的话,如果流状态不一致则返回Z_STREAM_ERROR,如果流是过早的释放

则返回Z_DATA_ERROR(一些输入或输出被丢弃)。这种错误发生时,msg可能被设置但为静态字符串

(不会被释放)。

*/



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用zlib库中的inflate()函数进行解压缩时,可能会遇到缓冲区满的情况。这时可以使用zlib库中的inflateReset()函数来清空缓冲区并重置解压器状态。 具体来说,当inflate()函数返回Z_BUF_ERROR错误码时,说明缓冲区已经满了。此时,可以调用inflateReset()函数来清空缓冲区并重置解压器状态,然后再调用inflate()函数继续解压缩。示例代码如下: ```c++ #include <zlib.h> int main() { // 初始化zlibzlibVersion(); // 定义输入数据和输出数据 char input_data[1024] = {0}; char output_data[1024] = {0}; // 初始化解压器 z_stream stream; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; stream.avail_in = 0; stream.next_in = Z_NULL; inflateInit(&stream); // 循环解压缩数据 int ret = 0; while (true) { // 读取输入数据到缓冲区 // ... // 设置解压器输入数据 stream.avail_in = input_data_len; stream.next_in = (Bytef*)input_data; // 解压缩数据到输出缓冲区 stream.avail_out = sizeof(output_data); stream.next_out = (Bytef*)output_data; ret = inflate(&stream, Z_NO_FLUSH); // 处理解压器返回值 if (ret == Z_BUF_ERROR) { // 缓冲区已满,调用inflateReset()函数清空缓冲区并重置解压器状态 inflateReset(&stream); continue; } else if (ret != Z_OK) { // 解压缩出错 // ... break; } // 处理输出数据 // ... // 检查解压器是否已经解压缩完所有数据 if (stream.avail_in == 0) { break; } } // 结束解压器 inflateEnd(&stream); return 0; } ``` 需要注意的是,如果输入数据中包含多个zlib数据块(也就是多次调用deflate()函数压缩的数据),那么在调用inflateReset()函数重置解压器状态后,需要重新设置解压器的解压缩参数(例如窗口大小等)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值