Поток инфляции Zlib не установлен в Z_STREAM_END в конце данных PNG IDAT - PullRequest
0 голосов
/ 11 ноября 2018

Я пытаюсь написать свой собственный 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 в качестве кода возврата в конце раздувания порции. Я дважды проверил, и в файле есть только один блок IDAT, chunkSize - это размер блока, взятого из заголовка блока, и оба compressedPixelData и pixelData - оба массива символов, выделенных с помощью * 1007. * байты памяти. pixelData содержит все содержимое блока IDAT (исключая контрольную сумму CRC).

Почему код возврата по-прежнему Z_OK вместо Z_STREAM_END после того, как весь блок IDAT был заполнен?

1 Ответ

0 голосов
/ 12 ноября 2018

Как указал Шон, распакованные данные больше, чем исходные входные данные. Увеличение размера stream.avali_out и выходного буфера pixelData решило проблему.

...