displacementmap renderer bug
SVG spec (http://www.w3.org/TR/SVG11/filters.html#feDisplacementMap) states that pixel values must be alpha-demultiplied before processing this filter operation. The following code does it, but when we DON'T do it, output is more similar to output from Batik.
if (map->mode == NR_PIXBLOCK_MODE_R8G8B8A8P){ alpha = (unsigned int) map_data[4*((x-x0) + width*(y-y0)) + 3]; if (alpha==0){ coordx = x-x0; coordy = y-y0; } else { coordx = x-x0 + scale * ( ((double)NR_DEMUL_111( (unsigned int)map_data[4*((x-x0) + width*(y-y0)) + Xchannel], alpha))/255 - 0.5 ); coordy = y-y0 + scale * ( ((double)NR_DEMUL_111( (unsigned int)map_data[4*((x-x0) + width*(y-y0)) + Ychannel], alpha))/255 - 0.5 ); } }
Batik output: http://bighead.poli.usp.br/~juca/code/inkscape/batik-fed02.png Inkscape output without demultiplication: http://bighead.poli.usp.br/~juca/code/inkscape/displacement-map-test.png
There is also this other bug that can be seen in the above screenshot: the lower and the right portions are not rendered, I dont know why.
JucaBlues
On Wed, 2007-07-25 at 22:35 -0300, Felipe Sanches wrote:
SVG spec (http://www.w3.org/TR/SVG11/filters.html#feDisplacementMap) states that pixel values must be alpha-demultiplied before processing this filter operation. The following code does it, but when we DON'T do it, output is more similar to output from Batik.
Are you certain that our pixel values are premultiplied? I know we've problems in some places where they aren't where they should be, and vice-versa.
-mental
On Wed, 2007-07-25 at 23:30 -0300, Felipe Sanches wrote:
well...
map->mode == NR_PIXBLOCK_MODE_R8G8B8A8P returns true
But are you sure the data is premultiplied? :) The problem is that I suspect sometimes we are populating such pixblocks with non-premultiplied data...
(it should be easy to check, in principle -- premultiplied data should never have any color components greater than the alpha component)
-mental
well... I have tested it using the folowing code inside the renderer method:
for (x=x0; x < x1; x++){ for (y=y0; y < y1; y++){ alpha = (unsigned int) map_data[4*((x-x0) + width*(y-y0)) + 3]; if ((unsigned int) map_data[4*((x-x0) + width*(y-y0))] > alpha || (unsigned int) map_data[4*((x-x0) + width*(y-y0)) + 1] > alpha || (unsigned int) map_data[4*((x-x0) + width*(y-y0)) + 2] > alpha) printf("I found a pixel with R,G or B greater than alpha!\n"); } }
when I select the .svg file on the file-section dialog I see this:
** (inkscape:28789): WARNING **: FIX-ME: FilterDisplacementMap::render method is still a bit buggy. Needs Love. I found a pixel with R,G or B greater than alpha!
** (inkscape:28789): WARNING **: FIX-ME: FilterDisplacementMap::render method is still a bit buggy. Needs Love. I found a pixel with R,G or B greater than alpha!
(the g_warning is at the beginning of the renderer method) and after opening the file:
** (inkscape:28789): WARNING **: FIX-ME: FilterDisplacementMap::render method is still a bit buggy. Needs Love.
** (inkscape:28789): WARNING **: FIX-ME: FilterDisplacementMap::render method is still a bit buggy. Needs Love.
** (inkscape:28789): WARNING **: FIX-ME: FilterDisplacementMap::render method is still a bit buggy. Needs Love.
This is nice! Apparently the input buffer is indeed premultiplied. I got puzzled by the single pixel that seems to have triggered the message during preview
On 7/26/07, MenTaLguY <mental@...3...> wrote:
On Wed, 2007-07-25 at 23:30 -0300, Felipe Sanches wrote:
well...
map->mode == NR_PIXBLOCK_MODE_R8G8B8A8P returns true
But are you sure the data is premultiplied? :) The problem is that I suspect sometimes we are populating such pixblocks with non-premultiplied data...
(it should be easy to check, in principle -- premultiplied data should never have any color components greater than the alpha component)
-mental
participants (2)
-
Felipe Sanches
-
MenTaLguY