lvandeve / lodepng

PNG encoder and decoder in C and C++.
zlib License
2.03k stars 420 forks source link

Lodepng fails to open valid png image #186

Closed az-faro closed 5 months ago

az-faro commented 5 months ago

The included perfectly valid png image can not be opened by lodepng. Multiple Windows programs and GIMP has no issues opening it. Trying to open it in lodepng results in error 58 (adler32 check).

Test file: test.png

lvandeve commented 5 months ago

There is definitely something wrong with the PNG image.

Adler32 check can be ignored with lodepng (with the ignore_adler32 setting), but even when doing that there are still other errors in the image with IDAT chunks.

Firefox also can't shows it correctly for me, it begins rendering the image progressively from the top and shows those contents, but at some point decides to stop and then displays a gray square with the URL in it instead of the image.

The imagemagick convert utility displays the following when trying to convert this image to another image format, which also shows something is truly wrong with this PNG:

$ convert 302563133-383c8b13-2559-4b23-af13-826bb4fcd2fb.png test.jpg
convert: bad adaptive filter value `302563133-383c8b13-2559-4b23-af13-826bb4fcd2fb.png' @ error/png.c/MagickPNGErrorHandler/1492.
convert: no images defined `test.jpg' @ error/convert.c/ConvertImageCommand/3362.

To be clear, 302563133-383c8b13-2559-4b23-af13-826bb4fcd2fb.png is the filename the test.png image above gets for me when downloading it from github

It's possible some image renderers are able to show something if it decodes the image horizontal line by horizontal line from top to bottom and already shows the first lines, since the error itself is only more towards the bottom part of the image. But LodePNG does not work line by line (yet, maybe some day...), it tries to decode all pixels at once first and then outputs them all, and when it encounters an encoding error stops with an error rather than output wrong pixels. So there is not much that can be done now.

az-faro commented 5 months ago

All I can say is that as stated above, all Windows image viewers I've used can open it and GIMP can open it. Neither of them shows corruption anywhere in the image. That doesn't mean the image isn't corrupt, but obviously they are in that case able to handle it gracefully and still decode the image.

Edit: Although actually when you mention it, there does seem to be a gray line in the lower middle of the image that I thought was part of the image due to what the image actually consists of, but looking closer at it that does look like corruption.

lvandeve commented 5 months ago

In theory LodePNG also could decode everything it can up to the point in the image where the error happens, which would be most of the image since the error is somewhere more towards the bottom part of the image.

It doesn't have a setting for this (it only has some settings to ignore checksum errors and a few other edge case errors now).

Perhaps this is a feature to consider, some sort of "recover as much of the image as you can" setting. It's just that, when this is enabled, you can't know what you get, it's just lucky that in this image most pixels are still fine, in others an error may be very early.

It's not that trivial to add this setting to LodePNG, because it does all the decompressing first, then all the pixel filtering, etc..., if an error happens in an earlier stage (like the decompressing) already, then it has to somehow handle doing the next stage only up to the part where the error was etc...

A streaming-decoding version of LodePNG that already outputs pixels as the bytes of the image come in would behave more like some of the image viewers that appear to work (since it'll be outputting pixels before even knowing that an error will be encountered further down in the image), but that feature is not at all implemented yet, it's one-shot decoding now.

az-faro commented 5 months ago

Well in that case I withdraw this issue as the image is obviously corrupt and not the fault of lodepng :)