Zlib Inflation stream not set to Z_STREAM_END at end of PNG IDAT data









up vote
1
down vote

favorite












I am trying to write my own PNG decoder for learning purposes. The code I'm using to decompress the data is below:



//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;


I get Z_OK as the return code at the end of inflating the chunk. I've double checked and there is only one IDAT chunk in the file, chunkSize is the size of the chunk taken from the header of the chunk, and both compressedPixelData and pixelData are both char arrays allocated with chunkSize bytes of memory. pixelData contains the entire contents of the IDAT chunk (excluding the CRC checksum).



Why is the return code still Z_OK instead of Z_STREAM_END, once the entire IDAT chunk has been inflated?










share|improve this question

















  • 1




    According to the documentation, Z_STREAM_END is not an error, and as valid as Z_OK. Error codes are negative, these two are not.
    – usr2564301
    Nov 11 at 20:41











  • Are you sure you're allocating enough space in in pixelData/stream.next_out and setting stream.avail_out to the right size? Or did that space get filled up by the one inflate call before decompressing all the data? Setting both stream.avail_in and stream.avail_out to the same value is strange.
    – Shawn
    Nov 11 at 20:54











  • @Shawn My understanding is that stream.avail_in is the number of bytes available to be decompressed, and stream.avail_out is the available space in the output buffer. Since I've set the output buffer to the same size as the full input buffer they are both the same value.
    – Adam0410
    Nov 11 at 21:04











  • @usr2564301 I know Z_STREAM_END is not an error state. It signifies the end of the stream of data to inflate. Since I've passed in all the data, I'm expecting to get Z_STREAM_END back, but instead I'm getting Z_OK.
    – Adam0410
    Nov 11 at 21:08






  • 1




    The output size is normally larger than the input size when decompressing, though... If you're using the same size there's still data left to decompress that there isn't room for in the output buffer you're using, hence Z_OK.
    – Shawn
    Nov 11 at 21:12















up vote
1
down vote

favorite












I am trying to write my own PNG decoder for learning purposes. The code I'm using to decompress the data is below:



//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;


I get Z_OK as the return code at the end of inflating the chunk. I've double checked and there is only one IDAT chunk in the file, chunkSize is the size of the chunk taken from the header of the chunk, and both compressedPixelData and pixelData are both char arrays allocated with chunkSize bytes of memory. pixelData contains the entire contents of the IDAT chunk (excluding the CRC checksum).



Why is the return code still Z_OK instead of Z_STREAM_END, once the entire IDAT chunk has been inflated?










share|improve this question

















  • 1




    According to the documentation, Z_STREAM_END is not an error, and as valid as Z_OK. Error codes are negative, these two are not.
    – usr2564301
    Nov 11 at 20:41











  • Are you sure you're allocating enough space in in pixelData/stream.next_out and setting stream.avail_out to the right size? Or did that space get filled up by the one inflate call before decompressing all the data? Setting both stream.avail_in and stream.avail_out to the same value is strange.
    – Shawn
    Nov 11 at 20:54











  • @Shawn My understanding is that stream.avail_in is the number of bytes available to be decompressed, and stream.avail_out is the available space in the output buffer. Since I've set the output buffer to the same size as the full input buffer they are both the same value.
    – Adam0410
    Nov 11 at 21:04











  • @usr2564301 I know Z_STREAM_END is not an error state. It signifies the end of the stream of data to inflate. Since I've passed in all the data, I'm expecting to get Z_STREAM_END back, but instead I'm getting Z_OK.
    – Adam0410
    Nov 11 at 21:08






  • 1




    The output size is normally larger than the input size when decompressing, though... If you're using the same size there's still data left to decompress that there isn't room for in the output buffer you're using, hence Z_OK.
    – Shawn
    Nov 11 at 21:12













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I am trying to write my own PNG decoder for learning purposes. The code I'm using to decompress the data is below:



//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;


I get Z_OK as the return code at the end of inflating the chunk. I've double checked and there is only one IDAT chunk in the file, chunkSize is the size of the chunk taken from the header of the chunk, and both compressedPixelData and pixelData are both char arrays allocated with chunkSize bytes of memory. pixelData contains the entire contents of the IDAT chunk (excluding the CRC checksum).



Why is the return code still Z_OK instead of Z_STREAM_END, once the entire IDAT chunk has been inflated?










share|improve this question













I am trying to write my own PNG decoder for learning purposes. The code I'm using to decompress the data is below:



//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;


I get Z_OK as the return code at the end of inflating the chunk. I've double checked and there is only one IDAT chunk in the file, chunkSize is the size of the chunk taken from the header of the chunk, and both compressedPixelData and pixelData are both char arrays allocated with chunkSize bytes of memory. pixelData contains the entire contents of the IDAT chunk (excluding the CRC checksum).



Why is the return code still Z_OK instead of Z_STREAM_END, once the entire IDAT chunk has been inflated?







c++ png zlib






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 20:31









Adam0410

4081828




4081828







  • 1




    According to the documentation, Z_STREAM_END is not an error, and as valid as Z_OK. Error codes are negative, these two are not.
    – usr2564301
    Nov 11 at 20:41











  • Are you sure you're allocating enough space in in pixelData/stream.next_out and setting stream.avail_out to the right size? Or did that space get filled up by the one inflate call before decompressing all the data? Setting both stream.avail_in and stream.avail_out to the same value is strange.
    – Shawn
    Nov 11 at 20:54











  • @Shawn My understanding is that stream.avail_in is the number of bytes available to be decompressed, and stream.avail_out is the available space in the output buffer. Since I've set the output buffer to the same size as the full input buffer they are both the same value.
    – Adam0410
    Nov 11 at 21:04











  • @usr2564301 I know Z_STREAM_END is not an error state. It signifies the end of the stream of data to inflate. Since I've passed in all the data, I'm expecting to get Z_STREAM_END back, but instead I'm getting Z_OK.
    – Adam0410
    Nov 11 at 21:08






  • 1




    The output size is normally larger than the input size when decompressing, though... If you're using the same size there's still data left to decompress that there isn't room for in the output buffer you're using, hence Z_OK.
    – Shawn
    Nov 11 at 21:12













  • 1




    According to the documentation, Z_STREAM_END is not an error, and as valid as Z_OK. Error codes are negative, these two are not.
    – usr2564301
    Nov 11 at 20:41











  • Are you sure you're allocating enough space in in pixelData/stream.next_out and setting stream.avail_out to the right size? Or did that space get filled up by the one inflate call before decompressing all the data? Setting both stream.avail_in and stream.avail_out to the same value is strange.
    – Shawn
    Nov 11 at 20:54











  • @Shawn My understanding is that stream.avail_in is the number of bytes available to be decompressed, and stream.avail_out is the available space in the output buffer. Since I've set the output buffer to the same size as the full input buffer they are both the same value.
    – Adam0410
    Nov 11 at 21:04











  • @usr2564301 I know Z_STREAM_END is not an error state. It signifies the end of the stream of data to inflate. Since I've passed in all the data, I'm expecting to get Z_STREAM_END back, but instead I'm getting Z_OK.
    – Adam0410
    Nov 11 at 21:08






  • 1




    The output size is normally larger than the input size when decompressing, though... If you're using the same size there's still data left to decompress that there isn't room for in the output buffer you're using, hence Z_OK.
    – Shawn
    Nov 11 at 21:12








1




1




According to the documentation, Z_STREAM_END is not an error, and as valid as Z_OK. Error codes are negative, these two are not.
– usr2564301
Nov 11 at 20:41





According to the documentation, Z_STREAM_END is not an error, and as valid as Z_OK. Error codes are negative, these two are not.
– usr2564301
Nov 11 at 20:41













Are you sure you're allocating enough space in in pixelData/stream.next_out and setting stream.avail_out to the right size? Or did that space get filled up by the one inflate call before decompressing all the data? Setting both stream.avail_in and stream.avail_out to the same value is strange.
– Shawn
Nov 11 at 20:54





Are you sure you're allocating enough space in in pixelData/stream.next_out and setting stream.avail_out to the right size? Or did that space get filled up by the one inflate call before decompressing all the data? Setting both stream.avail_in and stream.avail_out to the same value is strange.
– Shawn
Nov 11 at 20:54













@Shawn My understanding is that stream.avail_in is the number of bytes available to be decompressed, and stream.avail_out is the available space in the output buffer. Since I've set the output buffer to the same size as the full input buffer they are both the same value.
– Adam0410
Nov 11 at 21:04





@Shawn My understanding is that stream.avail_in is the number of bytes available to be decompressed, and stream.avail_out is the available space in the output buffer. Since I've set the output buffer to the same size as the full input buffer they are both the same value.
– Adam0410
Nov 11 at 21:04













@usr2564301 I know Z_STREAM_END is not an error state. It signifies the end of the stream of data to inflate. Since I've passed in all the data, I'm expecting to get Z_STREAM_END back, but instead I'm getting Z_OK.
– Adam0410
Nov 11 at 21:08




@usr2564301 I know Z_STREAM_END is not an error state. It signifies the end of the stream of data to inflate. Since I've passed in all the data, I'm expecting to get Z_STREAM_END back, but instead I'm getting Z_OK.
– Adam0410
Nov 11 at 21:08




1




1




The output size is normally larger than the input size when decompressing, though... If you're using the same size there's still data left to decompress that there isn't room for in the output buffer you're using, hence Z_OK.
– Shawn
Nov 11 at 21:12





The output size is normally larger than the input size when decompressing, though... If you're using the same size there's still data left to decompress that there isn't room for in the output buffer you're using, hence Z_OK.
– Shawn
Nov 11 at 21:12













1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










As pointed out by Shawn, the decompressed data is larger than the original input data. Increasing the size of stream.avali_out and the output buffer, pixelData fixed the issue.






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252960%2fzlib-inflation-stream-not-set-to-z-stream-end-at-end-of-png-idat-data%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    As pointed out by Shawn, the decompressed data is larger than the original input data. Increasing the size of stream.avali_out and the output buffer, pixelData fixed the issue.






    share|improve this answer
























      up vote
      2
      down vote



      accepted










      As pointed out by Shawn, the decompressed data is larger than the original input data. Increasing the size of stream.avali_out and the output buffer, pixelData fixed the issue.






      share|improve this answer






















        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        As pointed out by Shawn, the decompressed data is larger than the original input data. Increasing the size of stream.avali_out and the output buffer, pixelData fixed the issue.






        share|improve this answer












        As pointed out by Shawn, the decompressed data is larger than the original input data. Increasing the size of stream.avali_out and the output buffer, pixelData fixed the issue.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 11 at 21:18









        Adam0410

        4081828




        4081828



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252960%2fzlib-inflation-stream-not-set-to-z-stream-end-at-end-of-png-idat-data%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

            Museum of Modern and Contemporary Art of Trento and Rovereto