GNOME Bugzilla – Bug 163177
[pngdec] Can't cope with png's without an alpha channel
Last modified: 2005-01-09 01:40:00 UTC
Grab a png without an alpha channel, and decode it with pngdec, then re-encode it with pngenc, and observe that the result is somewhat disappointing. Problem lies in ext/libpng/gstpngdec.c, function gst_pngdec_chain, near the end, where the code reads: inp = GST_BUFFER_DATA (out); for (i = 0; i < height; i++) { rows[i] = inp; inp += width * 4; } That assumes that the thing is 32 bits wide, when it isn't. It is only 24. Two solutions exist: first, force libpng to add a dummy alpha channel (PNG_TRANSFORM_EXPAND flag, iirc), or to use pngdec->bpp / depth instead of that hard-coded 4. I can supply a patch for any of those (for now, I did the pngdec->bpp / depth thing, that one is more memory friendly, and pngdec only supports 8 bpp RGB+RGBA stuff now anyway).
Created attachment 35582 [details] [review] Patch fixing the problem Does two things: in gst_pngdec_src_getcaps(): sets up ->bpp. in gst_pngdec_chain(): uses that (together with the depth variable computed there) to determine the length of a line in bytes.
#162306 obsoletes this one, as the patch I submitted there fixes this problem too.
Created attachment 35670 [details] [review] Patch to fix the problem Compared to the previous patch, this does: Bail out earlier if encountering an image that has a bit_depth other than 8, free resources and unref the buffer on error paths in gst_pngdec_chain(), and add proper support for alpha channelled pngs. Instead of computing the length of the row ourselves when setting up row pointers for libpng, the patch makes pngdec use pngdec->info->rowbytes. Also, in gst_pngdec_chain(), only allocate just enough memory, so we don't send out too much data for nothing.
applied, thanks.