Cairo buffer data is stored in ARGB, and the following loop in ImageBufferCairo.cpp converts it to RGBA: if (unsigned int alpha = (*pixel & 0xff000000) >> 24) { destRows[basex] = (*pixel & 0x00ff0000) >> 16; destRows[basex + 1] = (*pixel & 0x0000ff00) >> 8; destRows[basex + 2] = (*pixel & 0x000000ff); destRows[basex + 3] = alpha; } else reinterpret_cast<uint32_t*>(destRows + basex)[0] = pixel[0]; The else clause looks suspicious, as it is assigning a ARGB value to where RGBA is expected. So instead of RGB0 you get 0RGB.
There is also concern of endianness with how color components are extracted from uint32.
Need to respect premultiplied colors: destRows[basex] = ((*pixel & 0x00ff0000) >> 16) * 255 / alpha; destRows[basex + 1] = ((*pixel & 0x0000ff00) >> 8) * 255 / alpha; destRows[basex + 2] = ((*pixel & 0x000000ff)) * 255 / alpha; destRows[basex + 3] = alpha; (the same on putImageData)
Created attachment 24331 [details] imageData This corrects the bugs and adds support for premultiplied colors. Todo: make it endian-save
Created attachment 24743 [details] canvas-getImageData.html output This is the output of canvas-getImageData.html after applying the patch. Like you can see many tests fail, because alpha channel is 1 "degree" lower than it should be. And perhaps thats why the other colors are wrong too. Because we use the alpha to get premultiplied colors.
Created attachment 24758 [details] color's given to GraphicsContext I checked the color that are given to GraphicsContext. I added the original alpha value on fist column and the second column includes the alpha multiplied with 255. As you can see (if you compare the values of the first list with the values of the second list): cairo gives the right values back (for the alpha channel). That means first: There is something wrong in Color.cpp and second: it shouldn't work on Cg either.
Created attachment 27216 [details] imageData respects pre-multiplied colors This fixes the pre-multiplied colors bug, as well as the alpha=0 case. It reads the colors, given to the context, correctly but fails on the canvas-getImageData test. But the fact, that the context gets the wrong color and getImageData reads exactly this color-settings, tells that getImageData works correctly. (see https://bugs.webkit.org/show_bug.cgi?id=22150) You can see the results of the test on the second attachment and the alpha of the colors, given to the context and therefor to the ImageBuffer, on the third attachement. You'll see, that the alpha channel is identical. (Haven't added all colors, but the result is the same) This patch passes canvas-putImageData. I talked about platform dependencies on IRC (#cairo). And they assure me, that this code is already endian safe.
Comment on attachment 27216 [details] imageData respects pre-multiplied colors Looks good. The +254 needs some thinking but I see where you got this code from (ImageBufferCG.cpp)
landed in r40542