c++ - Zlib Inflation 流未在 PNG IDAT 数据末尾设置为 Z_STREAM_END

标签 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;

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

为什么在整个 IDAT block 被膨胀后,返回代码仍然是 Z_OK 而不是 Z_STREAM_END

最佳答案

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

关于c++ - Zlib Inflation 流未在 PNG IDAT 数据末尾设置为 Z_STREAM_END,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53252960/

相关文章:

python - 如何在Python中创建多维数组typedef

c# - 如何使用 C# 将动态 XAML 转换为 PNG 或 GIF?

c - `stbi_failure_reason()` 不返回 SOI,但文件加载

node.js - NodeJS 流响应以防止内存不足错误

c++ - zlib inflate() 和网络链接上的数据丢失

c++ - 为什么 1 << 31 在 C++14 中改为实现定义?

c++释放包含自定义类的 vector 的内存

image - PNG 图像显示为白色背景,即使它具有清晰的背景

c++ - zlib 膨胀流和 avail_in

c++ - 通过 MSFT_NetAdapter 启用/禁用网络适配器