微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用非常旧的 zlib 来膨胀 gzip?

如何解决如何使用非常旧的 zlib 来膨胀 gzip?

我使用的 PPC 平台移植了旧版本的 zlib。是否可以使用 zlib 1.1.3 来扩充使用 gzip 1.5 制作的存档?

$ gzip --list --verbose vmlinux.z
method  crc     date  time           compressed        uncompressed  ratio uncompressed_name
defla 12169518 Apr 29 13:00             4261643             9199404  53.7% vmlinux

档案的前 32 个字节是

00000000  1f 8b 08 08 29 f4 8a 60  00 03 76 6d 6c 69 6e 75  |....)..`..vmlinu|
00000010  78 00 ec 9a 7f 54 1c 55  96 c7 6f 75 37 d0 fc 70  |x....T.U..ou7..p|

我已尝试使用此代码(其中 source 是指向 1f 8b 处第一个字节的指针)以及三个选项 A、B 和 C 用于 WBIT 初始化。

int ZEXPORT gunzip (dest,destLen,source,sourceLen)
    Bytef *dest;
    uLongf *destLen;
    const Bytef *source;
    uLong sourceLen;
{
    z_stream stream;
    int err;

    stream.next_in = (Bytef*)source;
    stream.avail_in = (uInt)sourceLen;
    /* Check for source > 64K on 16-bit machine: */
    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;

    stream.next_out = dest;
    stream.avail_out = (uInt)*destLen;
    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;

    stream.zalloc = (alloc_func)my_alloc;
    stream.zfree = (free_func)my_free;

    /* option A */
    err = inflateInit(&stream);
    /* option B */
    err = inflateInit2(&stream,15 + 16);
    /* option C */
    err = inflateInit2(&stream,-MAX_WBITS);
 
    if (err != Z_OK) return err;

    err = inflate(&stream,Z_FINISH);
    if (err != Z_STREAM_END) {
        inflateEnd(&stream);
        return err == Z_OK ? Z_BUF_ERROR : err;
    }
    *destLen = stream.total_out;

    err = inflateEnd(&stream);
    return err;
}

选项 A:

zlib inflate() 失败,错误为 Z_DATA_ERROR。 “未知的压缩方法
z_stream.avail_in  = 4261640
z_stream.total_in  = 1
z_stream.avail_out = 134152192
z_stream.total_out = 0

选项 B:

zlib inflateInit2_() 在第 118 行失败,出现 Z_STREAM_ERROR。
  /* set window size */
  if (w < 8 || w > 15)
  {
    inflateEnd(z);
    return Z_STREAM_ERROR;
  }

选项 C:

zlib inflate() 失败,错误为 Z_DATA_ERROR。 “无效的块类型”
z_stream.avail_in  = 4261640
z_stream.total_in  = 1
z_stream.avail_out = 134152192
z_stream.total_out = 0

解决方法

您的选项 B 适用于 zlib 1.2.1 或更高版本。

对于 zlib 1.1.3,有两种方法。

  1. 使用 gzopen()gzread()gzclose() 从文件中读取 gzip 流并解压到内存中。

  2. 要从内存中的 gzip 流解压缩,请使用选项 C,原始膨胀,之后手动解码 gzip 标头。使用 crc32() 在膨胀时计算解压缩数据的 CRC-32。膨胀完成后,手动解码 gzip 预告片,检查 CRC-32 和解压数据的大小。

gzip 头和尾的手动解码很容易实现。有关标题和预告片的说明,请参阅 RFC 1952

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。