我在将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
返回错误代码-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想要/需要什么准确?
这也是我尝试读取的图像的十六进制值的图片。 picture link because stackoverflow doesn't allow new users to post pics
答案 0 :(得分:1)
在78 5e ed d1 ...
之后的IDAT
是zlib流的开始。它的长度为288个字节,并且与所有PNG数据一样,都是有效的zlib流。如果您正确地读取了数据,将正确的部分充气并提供了足够的输出空间(请参阅下面的#2),那么它将起作用。
您对代码的一些评论:
compressBound()
在这里没有用。那仅用于压缩,而不用于解压缩。 228字节的压缩数据解压缩为47,234字节。