Reputation: 11
I'm having trouble inflating the png IDAT chunk back to RGB data.
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 error code -3, which means "Z_DATA_ERROR". I've followed the RFC-1950 and RFC-1951 standards but I'm confused as to which bytes actually need to be streamed into the inflate function and which need to be stripped.
m_data is literally just the data from the chunk without the length, type and CRC.
m_length in turn is only the length given by said chunk.
Input is also just plain RGB, with compression mode 0, filter mode 0 and interlace mode 0.
CM is 8.
CMINFO is 112.
FCHECK is 30.
FDICT is 0.
FLEVEL is 64.
TL;DR: what exactly does the inflate function from zlib want/need?
Here's also a picture of the hex values of the image I'm trying to read. picture link because stackoverflow doesn't allow new users to post pics
Upvotes: 0
Views: 762
Reputation: 112324
The 78 5e ed d1 ...
right after the IDAT
is the start of the zlib stream. It is 288 bytes long, and is a valid zlib stream, as is all of the PNG data. If you have read the data correctly, fed the correct portion to inflate, and provided enough output space (see #2 below), then it will work.
Some comments on your code:
compressBound()
is of no use here. That is only for compression, not decompression. That 228 bytes of compressed data decompresses to 47,234 bytes. Far more than you have allocated space for.Upvotes: 1