PNG IDAT数据结尾处的Zlib通货膨胀流未设置为Z_STREAM_END

时间:2018-11-11 20:31:49

标签: c++ png zlib

出于学习目的,我正在尝试编写自己的PNG解码器。我用来解压缩数据的代码如下:

//Stores the return code from the inflation stream
int returnCode;

//Tracks amount of data inflated
unsigned int dataReturned;

//Inflation stream
z_stream stream;

//Initalising the inflation state
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = chunkSize;
stream.next_in = compressedPixelData;

//Beginning the inflation stream

cout << "Beginning inflation" << endl;
returnCode = inflateInit(&stream);

//Checks for any errors with the inflation stream
if (returnCode != Z_OK)
    throw invalid_argument("Provided file is corrupted or does not use deflate as its compression algorithm");

//Pointing the stream to the output array
stream.avail_out = chunkSize;
stream.next_out = pixelData;

//Inflating the data
returnCode = inflate(&stream, Z_NO_FLUSH);

//Checking for errors
switch (returnCode) {

case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
    throw runtime_error("Error while decompressing pixel data. Either out of memory or the file is corrupted.");

}

dataReturned = chunkSize - stream.avail_out;
cout << dataReturned << endl;

//Ending the deflation stream and cleaning up

cout << "Return Code: " << returnCode << endl;
(void)inflateEnd(&stream);
delete[] compressedPixelData;

在填充块结束时,我得到Z_OK作为返回码。我已经仔细检查过,文件中只有一个IDAT块,chunkSize是从块头获取的块大小,compressedPixelDatapixelData都分配有chunkSize个字节内存的char数组。 pixelData包含IDAT块的全部内容(不包括CRC校验和)。

一旦整个IDAT块都被夸大了,为什么返回码仍然是Z_OK而不是Z_STREAM_END

1 个答案:

答案 0 :(得分:2)

正如Shawn所指出的,解压缩后的数据大于原始输入数据。 stream.avali_out和输出缓冲区的大小增加,pixelData解决了该问题。