Z_DATA_ERROR 试图膨胀 png IDAT 块时
Z_DATA_ERROR when trying to inflate png IDAT chunk
我在将 png IDAT 块膨胀回 RGB 数据时遇到问题。
void PNG::IDAT()
{
int index = 0;
char CMF = m_data[index];
index++;
//big endian
char CM = CMF & 0b00001111;
char CINFO = CMF & 0b11110000;
//For CM = 8, CINFO is the base-2 logarithm of the LZ77 window size, minus eight(CINFO = 7 indicates a 32K window size).
char FLG = m_data[index];
index++;
char FCHECK = FLG & 0b00011111;
//The FCHECK value must be such that CMF and FLG, when viewed as a 16 - bit unsigned integer stored in MSB order(CMF * 256 + FLG), is a multiple of 31. //effort
char FDICT = FLG & 0b00100000;
char FLEVEl = FLG & 0b11000000;
char DICTID[4];
if (FDICT > 0)
{
memcpy(DICTID, &m_data[index], 4);
index += 4;
}
uLong outputLength = compressBound(m_length);
char* output = new char[outputLength];
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = m_length; // size of input
infstream.next_in = (Bytef *)m_data; // input char array
infstream.avail_out = outputLength; // size of output
infstream.next_out = (Bytef *)output; // output char array
inflateInit2(&infstream, 16 + MAX_WBITS);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);
for (size_t i = 0; i < outputLength; i+= 3)
{
pixel temp;
temp.r = output[i + 0];
temp.g = output[i + 1];
temp.b = output[i + 2];
m_pixels.push_back(temp);
}
}
Inflate
returns错误代码-3,即"Z_DATA_ERROR"。我遵循了 RFC-1950 和 RFC-1951 标准,但我对哪些字节实际上需要流入 inflate 函数以及哪些字节需要被剥离感到困惑。
m_data 从字面上看只是块中的数据,没有长度、类型和 CRC。
m_length反过来只是所述块给出的长度。
输入也只是普通 RGB,压缩模式 0,过滤模式 0 和交错模式 0。
CM是8.
CMINFO 为 112。
FCHECK 为 30。
FDICT 为 0。
FLEVEL 是 64。
TL;DR:究竟 zlib want/need 中的膨胀函数是什么?
这也是我正在尝试读取的图像的十六进制值的图片。
picture link because Whosebug doesn't allow new users to post pics
IDAT
之后的 78 5e ed d1 ...
是 zlib 流的开始。它长 288 字节,是一个有效的 zlib 流,所有 PNG 数据也是如此。如果您正确读取了数据,输入了正确的部分进行膨胀,并提供了足够的输出 space(请参阅下面的 #2),那么它将起作用。
对您的代码的一些评论:
- 您无需尝试解码 zlib header。只需喂饱整个东西即可充气。
compressBound()
在这里没有用。那只是为了压缩,而不是解压。 228 字节的压缩数据解压缩为 47,234 字节。远远超过你为. 分配的space
- 生成的解压缩数据不是原始 RGB 像素。图像的每一行都以一个过滤字节开始,该行中剩余的字节需要相应地解释。
- 您需要检查 zlib 函数中的 return 代码和错误。 始终 检查 return 代码。总是。
我在将 png IDAT 块膨胀回 RGB 数据时遇到问题。
void PNG::IDAT()
{
int index = 0;
char CMF = m_data[index];
index++;
//big endian
char CM = CMF & 0b00001111;
char CINFO = CMF & 0b11110000;
//For CM = 8, CINFO is the base-2 logarithm of the LZ77 window size, minus eight(CINFO = 7 indicates a 32K window size).
char FLG = m_data[index];
index++;
char FCHECK = FLG & 0b00011111;
//The FCHECK value must be such that CMF and FLG, when viewed as a 16 - bit unsigned integer stored in MSB order(CMF * 256 + FLG), is a multiple of 31. //effort
char FDICT = FLG & 0b00100000;
char FLEVEl = FLG & 0b11000000;
char DICTID[4];
if (FDICT > 0)
{
memcpy(DICTID, &m_data[index], 4);
index += 4;
}
uLong outputLength = compressBound(m_length);
char* output = new char[outputLength];
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = m_length; // size of input
infstream.next_in = (Bytef *)m_data; // input char array
infstream.avail_out = outputLength; // size of output
infstream.next_out = (Bytef *)output; // output char array
inflateInit2(&infstream, 16 + MAX_WBITS);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);
for (size_t i = 0; i < outputLength; i+= 3)
{
pixel temp;
temp.r = output[i + 0];
temp.g = output[i + 1];
temp.b = output[i + 2];
m_pixels.push_back(temp);
}
}
Inflate
returns错误代码-3,即"Z_DATA_ERROR"。我遵循了 RFC-1950 和 RFC-1951 标准,但我对哪些字节实际上需要流入 inflate 函数以及哪些字节需要被剥离感到困惑。
m_data 从字面上看只是块中的数据,没有长度、类型和 CRC。
m_length反过来只是所述块给出的长度。
输入也只是普通 RGB,压缩模式 0,过滤模式 0 和交错模式 0。
CM是8.
CMINFO 为 112。
FCHECK 为 30。
FDICT 为 0。
FLEVEL 是 64。
TL;DR:究竟 zlib want/need 中的膨胀函数是什么?
这也是我正在尝试读取的图像的十六进制值的图片。 picture link because Whosebug doesn't allow new users to post pics
IDAT
之后的 78 5e ed d1 ...
是 zlib 流的开始。它长 288 字节,是一个有效的 zlib 流,所有 PNG 数据也是如此。如果您正确读取了数据,输入了正确的部分进行膨胀,并提供了足够的输出 space(请参阅下面的 #2),那么它将起作用。
对您的代码的一些评论:
- 您无需尝试解码 zlib header。只需喂饱整个东西即可充气。
compressBound()
在这里没有用。那只是为了压缩,而不是解压。 228 字节的压缩数据解压缩为 47,234 字节。远远超过你为. 分配的space
- 生成的解压缩数据不是原始 RGB 像素。图像的每一行都以一个过滤字节开始,该行中剩余的字节需要相应地解释。
- 您需要检查 zlib 函数中的 return 代码和错误。 始终 检查 return 代码。总是。