On 22/02/2008, Oliver Hunt [EMAIL PROTECTED] wrote:
At the moment the spec merely states that
putImageData(getImageData(sx,sy,..),sx,sy) should not
result in any visible change to the canvas, however for those
implementations that use a premultiplied buffer there is a necessary
premultiplication stage during blitting that results in a loss of precision
in some circumstances -- the most obvious being the case of alpha == 0, but
many other cases exist, eg. (254, 254, 254, alpha 255). This loss of
precision has no actual effect on the visible output, but does mean that in
the following case:
imageData = context.getImageData(0,0,...);
imageData.data[0]=254;
imageData.data[1]=254;
imageData.data[2]=254;
imageData.data[3]=1;
context.putImageData(imageData,0,0);
imageData2.data = context.getImageData(0,0,...);
At this point implementations that use premultiplied buffers can't
guarantee imageData.data[0] == imageData2.data[0]
Currently no UA can guarantee a roundtrip so i would suggest the spec be
updated to state that implementations do not have to guarantee a roundtrip
for any pixel where alpha 255.
The spec does not state that getImageData(putImageData(data)) == data,
which is where the problem would occur. It only states that
putImageData(getImageData) == identity function, which is not a
problem for premultiplied implementations (since the conversion from
premultiplied to non-premultiplied is lossless and reversible). So I
don't think the spec needs to change at all (except that it could have
a note mentioning the issue).
(getImageData can convert internal premultiplied (pr,pg,pb,a) into
ImageData's (r,g,b,a):
if (a == 0) {
r = g = b = 0;
} else {
r = (pr * 255) / a;
g = (pg * 255) / a;
b = (pb * 255) / a;
}
(using round-to-zero integer division). putImageData can convert the other way:
pr = (r*a + 254) / 255;
pg = (g*a + 254) / 255;
pb = (b*a + 254) / 255;
Then put(get()) has no effect on the values in the premultiplied buffer.)
--
Philip Taylor
[EMAIL PROTECTED]