Zlib Inflation 流未在 PNG IDAT 数据末尾设置为 Z_STREAM_END
Zlib Inflation stream not set to Z_STREAM_END at end of PNG IDAT data
出于学习目的,我正在尝试编写自己的 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 作为扩充块结束时的 return 代码。我仔细检查了文件中只有一个IDAT块,chunkSize
是从块头中取出的块大小,compressedPixelData
和pixelData
都是分配了 chunkSize
字节内存的 char 数组。 pixelData
包含 IDAT 块的全部内容(不包括 CRC 校验和)。
为什么 return 代码仍然是 Z_OK
而不是 Z_STREAM_END
,一旦整个 IDAT 块都被膨胀了?
Shawn 指出,解压后的数据比原始输入数据大。增加 stream.avali_out
和输出缓冲区的大小,pixelData
解决了这个问题。
出于学习目的,我正在尝试编写自己的 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 作为扩充块结束时的 return 代码。我仔细检查了文件中只有一个IDAT块,chunkSize
是从块头中取出的块大小,compressedPixelData
和pixelData
都是分配了 chunkSize
字节内存的 char 数组。 pixelData
包含 IDAT 块的全部内容(不包括 CRC 校验和)。
为什么 return 代码仍然是 Z_OK
而不是 Z_STREAM_END
,一旦整个 IDAT 块都被膨胀了?
Shawn 指出,解压后的数据比原始输入数据大。增加 stream.avali_out
和输出缓冲区的大小,pixelData
解决了这个问题。