-
Notifications
You must be signed in to change notification settings - Fork 738
Closed as not planned
Description
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 commentedon Nov 28, 2025
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:
@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 commentedon Nov 28, 2025
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 commentedon Nov 29, 2025
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 commentedon Nov 29, 2025
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_imageorpng_read_row:When using
png_process_data:ctruta commentedon Nov 29, 2025
@fintelia wrote:
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 commentedon Nov 29, 2025
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 commentedon Dec 8, 2025
Sorry. I thought you would create one using a HEX editor, but here is a sample:
damaged-PNG.zip