英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论