簡體   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