android - zlib inflate 返回 Z_BUF_ERROR

标签 android zlib

我正在从 android 客户端接收一个流,该流使用标准 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)

注意:输入流是原始压缩流(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;

最佳答案

您提供的压缩流inputStream[0..size-1]不完整。第三次调用 inflate() 已处理您提供的所有输入数据,但尚未看到 deflate 流的末尾。如果您此时检查 avail_in,您会发现它为零。

顺便说一句,您不需要设置data_type。这是由 zlib 设置的。它仅供引用,可以忽略。

关于android - zlib inflate 返回 Z_BUF_ERROR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22832953/

相关文章:

android - 通用窗口绘制图形并即时保存图像

android - buck构建因常量表达式所需的错误而失败

android - 单个设备中具有多个用户的应用程序 - 应用内计费订阅

android - WebView.setWebContentsDebuggingEnabled(false) 但我可以在安装已签名的 APK 后调试代码

带有 78 9C header 的数据库文件?

java - Android 选项卡,如何显示所选选项卡的图像

使用 zlib 库压缩多播数据包

c - 如何在 Visual Studio 2017 上将 zlib 编译成 DLL?

python-3.x - 了解 zlib header ; CMF(CM、CINFO)、FLG、(FDICT/DICTID、FLEVEL); RFC1950 § 2.2。数据格式

javascript - 使用内置模块压缩文件夹