Skip to content

Try rendering damaged PNG files. #762

@HT-7

Description

@HT-7

Currently, libpng (and by extension tools that rely on it, like xviewer and ffmpeg), are completely unable to render damaged PNG files, where as on Windows, the built-in image viewer and Microsoft Paint do try rendering a damaged PNG file.

Of course, the PNG file will appear with glitches, as would be expected from a damaged file, but that's still far better than showing nothing at all.

If the damage is near the end of a PNG file, most of the PNG file should still be able to be shown, but libpng doesn't try rendering the image at all.

Activity

jbowler

jbowler commented on Nov 28, 2025

@jbowler
Contributor

I believe I wrote both pieces of code. The Microsoft implementation is intended to do whatever (as in the US use of the word.) It's not a reference implementation.

The PNGv3 specification is unambiguous, @svgeesus and @ProgramMax, both authors of the specification, may care to dispute this. From section 13.1, describing error handling for decoders:

  • Recover from an error, if possible; otherwise fail gracefully. Errors that have little or no effect on the processing of the image may be ignored, while those that affect critical data shall be dealt with in a manner appropriate to the application.

@HT-7, please, when submitting an issue submit evidence. Opinion is, of course, always interesting but you didn't submit an example so what am I to assume, an image with a copyright violation maybe?

The libpng implementation is, authorities maintain, a reference implementation; not a correctly implemented tool for corporate advancement. As such decoding images with clear violations of the PNGv3 specification (remember, you presented no example) is a fault. libpng was not designed as a tool for corporate advancement; after all no one paid the implementors!

Were I to write the specification (I have never had a part in writing the PNG specification) I would have laid down clear, unambiguous and unequivocal rules for decoder handling of invalid images. But that's just me, it's a lot of work. Whatever.

fintelia

fintelia commented on Nov 28, 2025

@fintelia

It is also worth pointing out that libpng does provide options for decoding all sorts of corrupt PNGs files. You can disable validation of various checksums, ignore damaged non-critical chunks, overlook having too much or too little image data, and probably a bunch more issues I'm forgetting.

I have no inside information, but it is entirely possible that the applications that are rendering your damaged PNGs are also using libpng, but just with different settings.

jbowler

jbowler commented on Nov 29, 2025

@jbowler
Contributor

You can disable validation of various checksums

Not the Adler32 checksum; the code to do that (in libpng) was removed because it wasn't either portable (to Apple) or supported (by Mark). If the Adler32 is wrong the current line of the image is lost because both of the decode APIs (sequential and progressive) work by row. This does not happen in other implementations (in fact it didn't happen in libpng 1.7) because they decode by pixel.

It also doesn't happen if the Adler32 is split across an IDAT boundary because then the row (the last row of the image) is decoded successfully before the Adler32 generates the error code.

The same applies to other errors in the LZ77 stream, such as the bad-window-size error.

Errors aren't detectable in all cases however if the Adler32 is processed the chance of an undetected error is very small. However the libpng error mechanism does not allow a "continuable" error where the stream can be processed to completion even though the output may be garbage from a "non-continuable" error where the stream itself is broken (bad chunk length or name). It is essential for the information to be available to the application to know that an image is damaged.

fintelia

fintelia commented on Nov 29, 2025

@fintelia

Yeah, my statement that adler32 checksum validation can be disabled is an oversimplification. But since I spent way too much time collecting notes on libpng error behavior here, I might as well share them...

When using png_read_image or png_read_row:

  • Corrupt inflate data or bad adler32 while reading a row of pixels is an error.
  • Corrupt inflate data or bad adler32 checksum in the first non-empty IDAT following the last one containing image data is a benign error.

When using png_process_data:

  • Bad adler32 while reading pixels is a benign error.
  • Corrupt inflate stream or bad adler32 in an IDAT or png_process_data call after all pixels have been read is a warning.
ctruta

ctruta commented on Nov 29, 2025

@ctruta
Member

@fintelia wrote:

I have no inside information, but it is entirely possible that the applications that are rendering your damaged PNGs are also using libpng, but just with different settings.

I confirm that it is possible. OptiPNG (which uses libpng) can decode some of the broken PNGs and re-encode them "fixed" if the user enables the option -fix. Partially-downloaded PNG files, including those with CRC32 or Adler32 checksums bad or missing, are considered "fixable" by this program.

ctruta

ctruta commented on Nov 29, 2025

@ctruta
Member

I'm closing this issue as "Already Done" or "Not Planned", depending on how you look at my response.

The libpng API already allows the rendering of various kinds of out-of-spec images. Some kinds of "brokenness" can be allowed more easily than other kinds. Some of those are sufficient with a libpng function call, while others require a more involved implementation. Out-of-the-box libpng should follow the PNG specification to the letter, but if more flexibility is needed -- which depends on many factors and which can only be established on a case-by-case (broken-image-by-broken-image) basis -- then certain libpng API functions can be called to allow just that.

The emphasis is on case-by-case (broken-image-by-broken-image) basis.

HT-7

HT-7 commented on Dec 8, 2025

@HT-7
Author

remember, you presented no example

Sorry. I thought you would create one using a HEX editor, but here is a sample:

damaged-PNG.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jbowler@ctruta@fintelia@HT-7

        Issue actions