繁体   English   中英

zlib对avail_in和avail_out的充气/放气有什么保证?

[英]What guarantees does zlib's inflate/deflate make about avail_in and avail_out?

没有什么保障zlib给出的状态avail_inavail_out后调用inflate 我正在查看miniz特殊行为,我想确保这不是对zlib API的误解。 实际上,打完电话后inflate ,我已经avail_in非零和avail_out也非零,所以一些输入看起来是没有得到处理。 下面有更多详细信息。

我一直在使用miniz对从磁盘流到/从磁盘流过的文件进行膨胀/ 收缩 我的inflate / deflate循环与zpipe.c中的zlib示例相同,包括使用MZ_NO_FLUSH

这个循环几乎一直都起作用,但是今天我膨胀了一个早先放气的流,并始终得到MZ_DATA_ERROR 不过,在添加了适当的标头之后, gzip便可以对其进行良好的充气,并且我的数据是完整的。

我问题的根源在于对mz_inflate的最后一次调用。 我在这里包括典型的膨胀循环:

/* decompress until deflate stream ends or end of file */
do {
    strm.avail_in = fread(in, 1, CHUNK, source);
    if (ferror(source)) {
        (void)inflateEnd(&strm);
        return Z_ERRNO;
    }
    if (strm.avail_in == 0)
        break;
    strm.next_in = in;

    /* run inflate() on input until output buffer not full */
    do {
        strm.avail_out = CHUNK;
        strm.next_out = out;
        ret = inflate(&strm, Z_NO_FLUSH);
        assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
        switch (ret) {
        case Z_NEED_DICT:
            ret = Z_DATA_ERROR;     /* and fall through */
        case Z_DATA_ERROR:
        case Z_MEM_ERROR:
            (void)inflateEnd(&strm);
            return ret;
        }
        have = CHUNK - strm.avail_out;
        if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
            (void)inflateEnd(&strm);
            return Z_ERRNO;
        }
    } while (strm.avail_out == 0);

    /* done when inflate() says it's done */
} while (ret != Z_STREAM_END);

重复do内部do循环,直到处理avail_out所有当前块,并且avail_out具有额外空间avail_out 然而,在这个特别的流的最后一块, inflate并没有返回错误,而是会降低avail_in一些非零数字,并会减少avail_out 给一些(其他)非零数字。 因此,内部的do循环退出,因为avail_out不为零,并且我们尝试将更多数据放入next_inavail_in ,即使不是所有的avail_in都已经处理过,因为avail_in不为零。 这会破坏next_inavail_in并且在下一次调用时inflate失败。

我的解决方法是将内循环的终止条件从

strm.avail_out == 0

strm.avail_out == 0 || strm.avail_in > 0

但我不知道这是否正确。 我觉得这可能是miniz的错误,但不确定。 我本以为如果avail_in指示仍有数据要处理,则avail_out必须为零。

如果相关,我正在使用的输入缓冲区大小为512KB,输出缓冲区为2MB。

如果inflate()返回Z_OKZ_BUF_ERROR ,并且avail_out 为零,则avail_in 为零

您可以提供有问题的压缩数据吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM