image-png
image-png copied to clipboard
PNG image is erroneously blank when loaded by `image`
This happens in image v0.24.2
Expected
PNG image loaded and saved right back should have the same content (ignoring color space differences)
Actual behaviour
The attached image is completely transparent after being loaded and saved by image
:
Reproduction steps
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
use image::io::Reader as ImageReader;
let input = std::env::args().nth(1).unwrap();
let output = std::env::args().nth(2).unwrap();
let img = ImageReader::open(input)?.decode()?;
img.save(output)?;
Ok(())
}
invoked with image-convert in.png out.png
This sample aside, I am astonished how few divergences from other decoders I have found.
The entirety of my imageboard dataset (10,000 images, jpeg/gif/png) and a chunk of the wallhaven dataset (3k images, jpeg) decoded without a single divergence from imagemagick.
You all did an amazing job on this crate :+1:
emulsion
also displays the image as blank, so I think the saving step can be ruled out. It's the loading step that's the culprit.
pngcheck
reports an issue with the image:
$ pngcheck in.png
in.png invalid tRNS length for palette image
ERROR: in.png
I suspect what is happening is that when encountering invalid alpha information, we default to alpha=0 while other decoders default to alpha=255.
The tRNS chunk shall not contain more alpha values than there are palette entries, but a tRNS chunk may contain fewer values than there are palette entries. In this case, the alpha value for all remaining palette entries is assumed to be 255.
It seems that color palettes aren't handled properly in expand_paletted
.
That actually all seems to be handled as best as possible, as far as I can tell. tRNS consists of 174 nul-bytes.
(ChunkType { type: tRNS, critical: false, private: false, reserved: false, safecopy: false }, 174)
However, the palette only holds 173 entries! Hence, the detection of an invalid tRNS by pngcheck. Subsequently the whole chunk is most likely ignored by most other decoders.