【问题标题】:zlib inflate returning Z_BUF_ERRORzlib 膨胀返回 Z_BUF_ERROR
【发布时间】:2014-04-03 09:12:20
【问题描述】:

我正在接收来自 android 客户端的流,该流使用 standard zlib(链接到 -lz)进行压缩。以下方式尝试充气时,我得到Z_BUF_ERROR错误

if(!rawData)
    rawData= (char *)malloc(480 * 800 * 8);
int bufferLength = 128 * 1024;
char *tmpbuffer = malloc(bufferLength);
zUnzip.next_in = (Bytef *)inputStream;
zUnzip.avail_in = size;
zUnzip.next_out = (Bytef *)tmpbuffer; //output location of uncompressed stream
zUnzip.avail_out = bufferLength; //total size of output buffer
zUnzip.data_type = Z_BINARY;

inflateResult = inflateInit( &zUnzip); //standard zlib function, see <zlib.h>
if ( inflateResult != Z_OK ) {
    LOGE("inflateInit returned error: %d, msg: %s\n",inflateResult,zUnzip.msg);
}

do{
    inflateResult = inflate( &zUnzip, Z_SYNC_FLUSH );
    LOGE("avail_out = %d : difference = %d",zUnzip.avail_out,bufferLength-zUnzip.avail_out);
    memcpy(rawData,tmpbuffer,bufferLength);
    rawData+=bufferLength;
    zUnzip.next_out = (Bytef *)tmpbuffer; //output location of uncompressed stream
    zUnzip.avail_out = bufferLength; //total size of output buffer

}while(( inflateResult == Z_STREAM_END )) ;

if ( inflateResult < 0 ) {
        LOGE("zlib inflate returned error: %d, msg: %s\n",inflateResult,zUnzip.msg);
        return FALSE;
    }

大小为 16741 字节的 inputStream 的 logcat 输出

04-03 07:32:01.900: E/sc_client(25100): avail_out = 0 : difference = 131072
04-03 07:32:01.900: E/sc_client(25100): avail_out = 0 : difference = 131072
04-03 07:32:01.905: E/sc_client(25100): avail_out = 45672 : difference = 85400
04-03 07:32:01.905: E/sc_client(25100): avail_out = 131072 : difference = 0
04-03 07:32:01.905: E/sc_client(25100): zlib inflate returned error: -5, msg: (null)

注意:输入流是raw compressed stream(来自zlib deflate 调用的直接输出)!

更新:放气部分

rfbBool zrleOutStreamFlush(zrleOutStream *os){
  os->zs.next_in = os->in.start;
  os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in);

  while (os->zs.avail_in != 0) {
    do {
      int ret;
      os->zs.next_out = os->out.ptr;
      os->zs.avail_out = os->out.end - os->out.ptr;


      if ((ret = deflate(&os->zs, Z_SYNC_FLUSH)) != Z_OK) {
        Log("zrleOutStreamFlush: deflate failed with error code %d\n", ret);
        return FALSE;
      }

      os->out.ptr = os->zs.next_out;
    } while (os->zs.avail_out == 0);
  }

  os->in.ptr = os->in.start;
  LOGE("zrleOutStreamFlush: total_in %ld : total_out %ld ", os->zs.total_in,os->zs.total_out);
  return TRUE;
}

结构定义:

typedef struct {
  zrle_U8 *start; 
  zrle_U8 *ptr; //from start to ptr, we have data
  zrle_U8 *end;
} zrleBuffer;

typedef struct {
  zrleBuffer in; //input buffer
  zrleBuffer out; //output buffer

  z_stream   zs;
} zrleOutStream;

【问题讨论】:

    标签: android zlib


    【解决方案1】:

    您提供的压缩流inputStream[0..size-1] 不完整。第三次调用inflate() 已经处理了你提供的所有输入数据,但是还没有看到deflate 流的结束。如果您此时检查avail_in,您会看到它为零。

    顺便说一句,你不需要设置data_type。这是由 zlib 设置的。仅供参考,可以忽略。

    【讨论】:

    • 但是deflate调用生成的流是直接传给inflate的!那怎么流不完整呢?
    • 您一定是错误地收集了 deflate 的输出并确定了它的长度。您需要出示该代码。
    • 该代码与zrleOutStreamFlush函数中实现的代码相同。实际上我正在试验 zrle 编码/解码部分
    • 没有Z_FINISH 用于完成流。你应该看看这个annotated example for how to use zlib
    • 是的。如果你必须在最后一个块上循环,即如果在第一次调用后没有足够的输出空间来保存结果,那么继续使用Z_FINISH 调用直到你得到所有的输出。
    猜你喜欢
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 2014-07-25
    • 1970-01-01
    相关资源
    最近更新 更多