用gz *函数解压缩成功但是使用zlib的inflate *函数失败了

时间:2013-07-26 02:58:28

标签: gzip zlib compression inflate

我有一个带有标准gzip标头1F 8B 08 00 ...的gzip文件样本,当我用zlib中的inflate*函数对其进行膨胀时,输出只有11个字节(实际上输出应该是大约4KB) ,但是当我用gz*函数解压缩它时,它产生正确的输出,代码:

  1. 使用gz*(这可以产生正确的输出):

    #define CHUNK 10240
    int gz_decompress(const char *path) {
        gzFile f = gzopen(path, "rb");
        if(!f)
            return -1;
    
        unsigned char result[CHUNK];
        int bytes_read = gzread(f, result, CHUNK);
        if(bytes_read < CHUNK)
            if(!gzeof(f))
                return -2;
        gzclose (f);
        return 0;
    }
    
  2. 使用inflate*(输出只有11个字节):

    #define CHUNK 10240
    int inf(FILE *source)
    {
        int ret;
        unsigned have;
        z_stream strm;
        unsigned char in[CHUNK];
        unsigned char out[CHUNK];
    
        /* allocate inflate state */
        strm.zalloc = Z_NULL;
        strm.zfree = Z_NULL;
        strm.opaque = Z_NULL;
        strm.avail_in = 0;
        strm.next_in = Z_NULL;
        // ret = inflateInit(&strm);
        ret = inflateInit2(&strm, 16 + 15);
        if (ret != Z_OK)
            return ret;
    
        /* decompress until deflate stream ends or end of file */
        do {
            strm.avail_in = fread(in, 1, CHUNK, source);
            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;
            } while (strm.avail_out == 0);
    
            /* done when inflate() says it's done */
        } while (ret != Z_STREAM_END);
    
        /* clean up and return */
        (void)inflateEnd(&strm);
        return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
    }
    
  3. 事实上,第二个代码段来自官方zlib用法示例zpipe.c,我根据this zlib gzip discussion仅将inflateInit(&strm);的调用更改为inflateInit2(&strm, 16 + 15);,但现在我不知道为什么会失败,任何人都可以帮忙?

1 个答案:

答案 0 :(得分:0)

根据您的评论,inf()正在返回Z_OK,这意味着gzip流已成功解压缩并经过验证。

你的意思是“输出只有11个字节”?您的inf()函数根本不会产生任何输出。