Zlib解压与C不同?

huangapple go评论122阅读模式
英文:

Zlib inflate works differently to C?

问题

我正在尝试在Java中对字节数组进行zlib解压缩,但是在解压缩时未返回Z_STREAM_END。我的代码与我查看的一些C代码完全相同,这些C代码与相同的数据、滑动窗口和其他参数一起使用,我认为是吗?我正在使用JZlib。以下是我的Java代码(dgboff只是文件中此zlib字节数组的偏移量):

private byte[] z_decompress(byte[] in, int insize, byte[] out, int outsize) {
    ZStream zlib = new ZStream();
    zlib.inflateInit(15); // 32k window (2^15)
    zlib.next_in = in;
    zlib.avail_in = insize;
    zlib.next_out = out;
    zlib.avail_out = outsize;
    if (zlib.inflate(JZlib.Z_FINISH) != JZlib.Z_STREAM_END) {
        System.out.println("Incomplete zlib input at offset " + dgboff + ". Compressed size: " + insize + ", uncompressed size: " + outsize);
        System.exit(1);
    }
    zlib.inflateEnd();
    return zlib.next_out;
}

以下是可以正常工作的C代码(忽略混乱的间距):

z = calloc(1, sizeof(z_stream));
if (!z) std_err();
z->zalloc = (alloc_func)0;
z->zfree = (free_func)0;
z->opaque = (voidpf)0;
if (inflateInit2(z, 15)) {
    printf("\nError: initialization error\n");
    exit(1);
}
inflateReset(z);

z->next_in = in;
z->avail_in = insz;
z->next_out = out;
z->avail_out = outsz;
if (inflate(z, Z_FINISH) != Z_STREAM_END) {
    printf("\nError: the compressed zlib/deflate input at offset 0x%08x (%d -> %d) is wrong or incomplete\n", (int)g_dbg_offset, (int)insz, (int)outsz);
    exit(1);
}
// 在C代码中到达这里

如果我漏掉了什么,请告诉我!

我正在测试的数据的zlib头部是0x649d。

英文:

I am trying to zlib inflate a byte array in java, however I am not getting the Z_STREAM_END returned when I inflate it.
I have the code exactly the same as some C code I viewed which worked with the same data, sliding window and other parameters (I think?).
I am using JZlib. Here is my Java code (dgboff is just the offset of this zlib byte array in a file):

private byte[] z_decompress(byte[] in,int insize,byte[] out,int outsize) {
	ZStream zlib = new ZStream();
	zlib.inflateInit(15);//32k window (2^15)
	zlib.next_in=in;
	zlib.avail_in=insize;
	zlib.next_out=out;
	zlib.avail_out=outsize;
	if(zlib.inflate(JZlib.Z_FINISH)!=JZlib.Z_STREAM_END) {
		System.out.println("Incomplete zlib input at offset "+dgboff+". Compressed size: "+insize+", uncompressed size: "+outsize);
		System.exit(1);
	}
	zlib.inflateEnd();
	return zlib.next_out;
}

and here is the C code, which works (ignore the messy spacing):

 z = calloc(1, sizeof(z_stream)); 
    if(!z) std_err(); 
    z->zalloc = (alloc_func)0; 
    z->zfree  = (free_func)0; 
    z->opaque = (voidpf)0; 
if(inflateInit2(z, 15)) { 
        printf("\nError: initialization error\n"); 
        exit(1); 
 } 
inflateReset(z);

z->next_in   = in;
z->avail_in  = insz;
z->next_out  = out;
z->avail_out = outsz;
if(inflate(z, Z_FINISH) != Z_STREAM_END) {
    printf("\nError: the compressed zlib/deflate input at offset 0x%08x (%d -> %d) is wrong or incomplete\n", (int)g_dbg_offset, (int)insz, (int)outsz);
    exit(1);
}
//gets to here in C

If there is anything I am missing please tell me!

The zlib header for the data I am testing is 0x649d.

答案1

得分: 1

你的数据不是一个zlib流,也没有zlib头部。它是一个原始的deflate流。你展示的两个代码示例都不能正常工作。你所说的“这是可行的C代码”肯定是其他的C代码。

要解压原始的inflate数据,你需要在inflateInit2()的第二个参数中使用-15(而不是15)。

顺便说一下,你提供的链接中的deflate压缩数据是不完整的。它在所涵盖的部分上是正确的,但没有终止标志。

英文:

Your data is not a zlib stream, and does not have a zlib header. It is a raw deflate stream. Neither of your code examples as shown could have worked. Your "here is the C code, which works" must have been some other C code.

To decompress raw inflate data, you need to use -15 (instead of 15) as the second argument of inflateInit2().

By the way, the deflate compressed data you provided a link for is incomplete. It is correct as far as it goes, but it does not terminate.

huangapple
  • 本文由 发表于 2020年7月23日 07:05:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/63044414.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定