Fix #358 #430
Fix #358 #430
Conversation
Changes the PNG reader for paletted images to use the index of a pixel to decide its transparency, rather than its color. This caused pixels with non-zero index to be transparent if their index's color happened to be the same as index 0's color. Unfortunately, the indexed color -> RGBA conversion was being done in libpng, so EasyRPG never saw the indices to begin with. So it requires fairly invasive changes. For the sake of symmetry, I pulled out functions for non-indexed images too. Not very pretty.
When writing a row of pixel data, instead of using a temporary
buffer of width w to hold the indices, put them in the last
w bytes of the row of pixel data. Then the index->RGBA loop looks
like
read nth index (from offset 3w+n)
convert to color
write color to nth pixel (offsets 4n..4n+3)
To check we don't overwrite a byte holding an index we'll later
need, we need to know that the offset of the last byte written,
4n+3, is less than the offset of the next byte read, 3w+(n+1).
4n+3 < 3w+(n+1) is equivalent to n < w-2/3, which is true since
n <= w-1.
|
Thanks scurest, looks a clever way to fix this. I was thinking on getting a transparent mask then applying them after but I was feeling it dirtier as it was requiring to modify the transparent palette calculation code when the issue was really in the PNG handling. Not tested but I guess this should work fine with BMP and XYZ image readers. About the temporary array allocation removal adds some extra operations on a nested for I think won't make much slower the conversion, so looks good to me About |
|
fdelapena, thanks. About 16-bit depth, it's probably just me being finicky. You're right about indexed images not having 16-bit depths, so I took those out along, with the <8-bit depths for GRAY_ALPHA, RGB, and RGBA, which were also impossible. |
|
Thanks, tested and working fine, now the new methods don't require the parameter: By the way, if you want to silence these warnings in image_png.cpp in the same pull request would be nice: Other tested formats for this bug (BMP, XYZ) are working fine. |
Removes unused parameters, some alignment, and signed/unsigned comparison. Also adds a missing cleanup case to WritePNG.
|
Oops, that was careless. Should be fixed. Also added some cleanup on the |
This fixes #358.
The cause was pretty obvious: transparency was being decided based on color (ie. is this pixel's index's color the color of index 0?) instead of index (ie. is this pixel's index 0?). Unfortunately, since EasyRPG never saw the indices (libpng handled it) this required a new path for handling indexed images with transparency, and then I wanted a new path for grayscale images to handle their transparency, and then I just pulled the rest of the image types out for the sake of symmetry, and that's how I got such an ugly commit :( Changes welcome.
DoesReadPalettedDataneed theif (bit_depth == 16)check?I usedmallocfor the temporary buffer inReadPalettedDatajust because that's whatpixelsused, but should I prefernew[]?I didn't test a grayscale image. Someone should probably do that.Seems fine.(This is me reading the libpng docs)