lvandeve / lodepng

PNG encoder and decoder in C and C++.
zlib License
2.06k stars 421 forks source link

LodePNG unnecessarily remaps colours when reading a paletted PNG (requesting LCT_PALETTE paletted ouput) #68

Closed rversteegen closed 6 years ago

rversteegen commented 6 years ago

I have a png file with a palette, and the palette contains duplicate colors. I read the file, passing

    state.info_raw.colortype = LCT_PALETTE
    state.info_raw.bitdepth = 8

to lodepng_decode. (I want both the value of each pixel, as a palette index, and the palette.) Unfortunately, lodepng_decode performs an unnecessary call to lodepng_convert, which causes the original palette indices to be lost.

The problem is this check in lodepng_color_mode_equal:

  /*if one of the palette sizes is 0, then we consider it to be the same as the
  other: it means that e.g. the palette was not given by the user and should be
  considered the same as the palette inside the PNG.*/
  if(1/*a->palettesize != 0 && b->palettesize != 0*/) {

In this case a->palettesize is 0, because I didn't pass a palette to lodepng_decode. I don't know why this is commented out; the git log is uninformative. Uncommenting it fixes the bug for me but maybe it breaks something else.

Luckily there is a very easy workaround:

    state.decoder.color_convert = 0
rversteegen commented 6 years ago

audio2 map 0 layer 0

Oh, and here's a testcase. Some examples of pixels: at (0,0): lodepng_decode returns 194, should be 144 at (2,1): lodepng_decode returns 200, should be 152 at (3,1): lodepng_decode returns 208, should be 0

(BTW, very nice library, and extremely well documented. Thank you!)

lvandeve commented 6 years ago

Thanks for reporting!

I removed the "if(1)" and found a better location to fix it. https://github.com/lvandeve/lodepng/commit/d03d7df9888aafb9c7f615895c34b05acf033908 should fix it