Menu

#265 Extra 0 length IDAT Chunk at end of 8192 Byte aligned .png files.

libpng_code
closed-fixed
None
5
2017-06-29
2017-06-02
Brian Baird
No

Greetings,

We have recently updated our OpenCV from 3.0 to 3.2. Along with this came libpng 1.6.24 [August 4, 2016].
After running our regression tests we found that a few of our image files failed the binary comparison test. After some research it appears that if a .png is written that has 8192 bytes in its final IDAT chunk there will be one additional IDAT chunk written with 0 bytes.

Attached is such an image before and after along with some screenshots of the chunks and a snippet of code which can create this issue.

Kindest regards,

Brian Baird

1 Attachments

Discussion

  • Glenn Randers-Pehrson

    • assigned_to: Glenn Randers-Pehrson
     
  • Glenn Randers-Pehrson

    Thanks for the report. Would you try building with the current libpng (1.6.29)?

     
    • Brian Baird

      Brian Baird - 2017-06-05

      I'm not having much luck getting 1.6.29 to compile as part of the OpenCV 3.2, sorry. Any luck on your end?

       
      • Glenn Randers-Pehrson

        Nope. I'll see if I can reproduce the problem in another libpng16 application.

         

        Last edit: Glenn Randers-Pehrson 2017-06-05
  • Glenn Randers-Pehrson

    Which platform were you testing (unix, ios, win, or android)?

     
    • Brian Baird

      Brian Baird - 2017-06-03

      Windows 7

       
  • Glenn Randers-Pehrson

    Confirmed with pngcrush+libpng16-1.6.29; it generates an extra zero-length IDAT when the last IDAT is the maximum buffer size. So it's a libpng16 off-by-one problem.

     

    Last edit: Glenn Randers-Pehrson 2017-06-05
  • Glenn Randers-Pehrson

    Confirmed that pngcrush+libpng15-1.5.29beta does not exhibit the bug and that
    pngcrush+libpng16-1.6.13 does exhibit the bug.

     

    Last edit: Glenn Randers-Pehrson 2017-06-05
  • Glenn Randers-Pehrson

    Confirmed that libpng-1.6.0 exhibits the bug. I'm using "pngtest" that comes with libpng; I add the following:

    // set compression flags here.
       png_set_compression_buffer_size(write_ptr,
           (png_size_t)8119);
    

    where the value "8119" is the exact length of the IDAT chunks
    in pngout.png after running pngtest. The r esult is, as expected,
    one IDAT with length 8119 followed by an IDAT of length 0.

     
  • Brian Baird

    Brian Baird - 2017-06-06

    Excellent news! Great work and thanks for looking into this.

     
  • Glenn Randers-Pehrson

    I'll post a fixed libpng16 shortly. The fix is just to add "if (size)" before each of the two calls to png_write_complete_chunk(...IDAT...) in pngwutil.c (probably only needed before the
    second call).

     

    Last edit: Glenn Randers-Pehrson 2017-06-06
  • Glenn Randers-Pehrson

    Confirmed that libpng17 does not have the bug.

     
  • Glenn Randers-Pehrson

    Fixed in libpng-1.6.30beta04. Coverity did not object to either "if (size)" so I kept both.

     
  • Glenn Randers-Pehrson

    Fixed in libpng-1.6.30

     
  • Glenn Randers-Pehrson

    • status: open --> closed-fixed
     

Log in to post a comment.