I'm trying to decompress a zip file using zlib (without using any extension or 3rd party). Initially, the src_len is 48756255, and the dest_len is 49209890. The first pass in the while loop is fine: err is Z_OK and the second pass through starts. On the second pass, no matter what I do I get a Z_BUF_ERROR from inflate. stream.total_out at this point is 49034460, so there is a bit remaining but stream.avail_in on the second pass is 0. In any case, I would expect inflate to give me Z_STREAM_END. I really don't know what's going on, can anyone help?
我正在尝试使用zlib解压缩一个zip文件(不使用任何扩展或第三方)。最初,src_len是48756255,而dest_len是49209890。while循环的第一个传递是fine: err是Z_OK,第二个是通过start。在第二个通道上,无论我做什么,我都会从膨胀中得到Z_BUF_ERROR。流。此时的total_out是49034460,所以剩下的部分是流。第二次通过的时候是0。在任何情况下,我都期望膨胀给我Z_STREAM_END。我真的不知道发生了什么,有人能帮忙吗?
void compression::uncompress2(char* dest, unsigned dest_len, char* src, unsigned src_len) {
TempAllocator ta;
z_stream_s stream = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
stream.next_in = (Bytef*)src;
stream.avail_in = (uInt)src_len;
stream.next_out = (Bytef*)dest;
stream.avail_out = (uInt)dest_len;
stream.zalloc = zalloc;
stream.zfree = zfree;
stream.opaque = &ta;
// no header
int err = inflateInit2(&stream, -MAX_WBITS);
XENSURE(err == Z_OK);
bool done = false;
while (!done) {
stream.next_out = (Bytef*)(dest + stream.total_out);
stream.avail_out = dest_len - stream.total_out;
err = inflate(&stream, Z_SYNC_FLUSH);
if (err == Z_STREAM_END)
done = true;
else if (err != Z_OK) {
break;
}
}
err = inflateEnd(&stream);
XENSURE(err == Z_OK);
}
1 个解决方案
#1
5
inflate()
will process as much input as possible using the available output. Once it can neither process input nor produce output, it will return Z_BUF_ERROR
.
通过使用可用的输出来处理尽可能多的输入。一旦它既不能处理输入,也不能产生输出,它将返回Z_BUF_ERROR。
In this case, all of the input is processed and there is output room to spare, but the end of the stream is not detected. You are not getting Z_STREAM_END
because for some reason you are not providing a complete deflate stream.
在这种情况下,所有的输入都是经过处理的,并且有多余的输出空间,但是没有检测到流的末端。您没有得到Z_STREAM_END,因为某些原因您没有提供一个完整的压缩流。
Here are some other comments on your code. Your loop does nothing, and setting next_out
and avail_out
in the loop as you do does nothing. You are providing no new input nor new output space in your loop, so there is no point in having a loop. The only purpose of having a loop around inflate()
is to either provide more input, provide more output space, or both. Furthermore when inflate()
returns, next_out
and avail_out
are updated to the next available location in the output buffer and the amount of available space there. Your statements that set next_out
and avail_out
in the loop set those to the values they already have.
以下是对您的代码的一些其他评论。您的循环不做任何事情,并且在循环中设置next_out和avail_out,因为您什么都不做。您在循环中没有提供新的输入或新的输出空间,因此没有必要进行循环。围绕膨胀()的唯一目的是提供更多的输入,提供更多的输出空间,或者两者都有。此外,当虚增()返回时,next_out和avail_out被更新到输出缓冲区中的下一个可用位置和那里可用空间的数量。在循环中设置next_out和avail_out的语句将它们设置为它们已经拥有的值。
In code with proper loops around inflate()
, a Z_BUF_ERROR
is not a problem, and the processing can continue. Though if you expect a different result on the next call of inflate()
, more input and/or more output space must be provided.
在使用适当的循环来进行膨胀()的代码中,Z_BUF_ERROR不是问题,并且处理可以继续。但是,如果您期望在下一次调用膨胀()时得到不同的结果,则必须提供更多的输入和/或更多的输出空间。
There is no need to initialize stream
with a structure of zeros. The subsequent assignments are all you need.
不需要使用零结构来初始化流。接下来的作业是您所需要的。
#1
5
inflate()
will process as much input as possible using the available output. Once it can neither process input nor produce output, it will return Z_BUF_ERROR
.
通过使用可用的输出来处理尽可能多的输入。一旦它既不能处理输入,也不能产生输出,它将返回Z_BUF_ERROR。
In this case, all of the input is processed and there is output room to spare, but the end of the stream is not detected. You are not getting Z_STREAM_END
because for some reason you are not providing a complete deflate stream.
在这种情况下,所有的输入都是经过处理的,并且有多余的输出空间,但是没有检测到流的末端。您没有得到Z_STREAM_END,因为某些原因您没有提供一个完整的压缩流。
Here are some other comments on your code. Your loop does nothing, and setting next_out
and avail_out
in the loop as you do does nothing. You are providing no new input nor new output space in your loop, so there is no point in having a loop. The only purpose of having a loop around inflate()
is to either provide more input, provide more output space, or both. Furthermore when inflate()
returns, next_out
and avail_out
are updated to the next available location in the output buffer and the amount of available space there. Your statements that set next_out
and avail_out
in the loop set those to the values they already have.
以下是对您的代码的一些其他评论。您的循环不做任何事情,并且在循环中设置next_out和avail_out,因为您什么都不做。您在循环中没有提供新的输入或新的输出空间,因此没有必要进行循环。围绕膨胀()的唯一目的是提供更多的输入,提供更多的输出空间,或者两者都有。此外,当虚增()返回时,next_out和avail_out被更新到输出缓冲区中的下一个可用位置和那里可用空间的数量。在循环中设置next_out和avail_out的语句将它们设置为它们已经拥有的值。
In code with proper loops around inflate()
, a Z_BUF_ERROR
is not a problem, and the processing can continue. Though if you expect a different result on the next call of inflate()
, more input and/or more output space must be provided.
在使用适当的循环来进行膨胀()的代码中,Z_BUF_ERROR不是问题,并且处理可以继续。但是,如果您期望在下一次调用膨胀()时得到不同的结果,则必须提供更多的输入和/或更多的输出空间。
There is no need to initialize stream
with a structure of zeros. The subsequent assignments are all you need.
不需要使用零结构来初始化流。接下来的作业是您所需要的。