[whatwg] More ImageData issues
Philip Taylor
excors+whatwg at gmail.com
Tue Apr 29 18:31:07 PDT 2008
On 22/02/2008, Oliver Hunt <oliver at apple.com> 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
excors at gmail.com
More information about the whatwg
mailing list