Bug 73952

Summary: canvas/philip/tests/2d.imageData.put.unchanged.html expects putImageData/getImageData to exactly preserve unpremul-alpha pixel values
Product: WebKit Reporter: Brian Salomon <bsalomon>
Component: Tools / TestsAssignee: Nobody <webkit-unassigned>
Status: RESOLVED CONFIGURATION CHANGED    
Severity: Normal CC: bfulgham, mdelaney7, noel.gordon, senorblanco
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
URL: http://philip.html5.org/tests/canvas/suite/tests/2d.imageData.put.unchanged.html

Description Brian Salomon 2011-12-06 14:04:12 PST
This canvas test calls getImageData, makes a copy of the image data, does putImageData at the same location, and then does another getImageData. It fails if there are any differences in the pixel values retrieved by the two getImageDatas. Just below the section of the spec referenced by the test (http://philip.html5.org/tests/canvas/suite/tests/spec.html#testrefs.2d.imageData.unchanged) is this note:

"Due to the lossy nature of converting to and from premultiplied alpha color values, pixels that have just been set using putImageData() might be returned to an equivalent getImageData() as different values."

It seems that the test should perform a fuzzy comparison.
Comment 1 Stephen White 2011-12-06 15:01:21 PST
Actually, I think the test link is referring to this statement:

"The handling of pixel rounding when the specified coordinates do not exactly map to the device coordinate space is not defined by this specification, except that the following must result in no visible changes to the rendering # 2d.imageData.put.unchanged :

context.putImageData(context.getImageData(x, y, w, h), p, q);"

So although the mult/premult changes are lossy, in order to be spec-compliant, I think you have to be value-preserving over one roundtrip.
Comment 2 Brian Salomon 2011-12-07 06:50:17 PST
(In reply to comment #1)
> Actually, I think the test link is referring to this statement:
> 
> "The handling of pixel rounding when the specified coordinates do not exactly map to the device coordinate space is not defined by this specification, except that the following must result in no visible changes to the rendering # 2d.imageData.put.unchanged :
> 
> context.putImageData(context.getImageData(x, y, w, h), p, q);"
> 
> So although the mult/premult changes are lossy, in order to be spec-compliant, I think you have to be value-preserving over one roundtrip.

My take is that the rounding language refers to rounding coordinates to the pixel grid. The test seems to be exercising this by doing its get/put at coordinate (.1, .2) rather than (0, 0). Also it says "no visible change" not no change at all. The later language about premultiplying seems to indicate that a roundtrip may come back as "different values."
Comment 3 Brian Salomon 2011-12-07 08:20:53 PST
(In reply to comment #2)
> (In reply to comment #1)
> > Actually, I think the test link is referring to this statement:
> > 
> > "The handling of pixel rounding when the specified coordinates do not exactly map to the device coordinate space is not defined by this specification, except that the following must result in no visible changes to the rendering # 2d.imageData.put.unchanged :
> > 
> > context.putImageData(context.getImageData(x, y, w, h), p, q);"
> > 
> > So although the mult/premult changes are lossy, in order to be spec-compliant, I think you have to be value-preserving over one roundtrip.
> 
> My take is that the rounding language refers to rounding coordinates to the pixel grid. The test seems to be exercising this by doing its get/put at coordinate (.1, .2) rather than (0, 0). Also it says "no visible change" not no change at all. The later language about premultiplying seems to indicate that a roundtrip may come back as "different values."

Take a look at the entire paragraph that the sentence beginning with "The handling..." is part of:

<quote>
The handling of pixel rounding when the specified coordinates do not exactly map to the device coordinate space is not defined by this specification, except that the following must result in no visible changes to the rendering # 2d.imageData.put.unchanged :

context.putImageData(context.getImageData(x, y, w, h), p, q);
...for any value of x, y, w, and h and where p is the smaller of x and the sum of x and w, and q is the smaller of y and the sum of y and h; and except that the following two calls:

context.createImageData(w, h);
context.getImageData(0, 0, w, h);
...must return ImageData objects with the same dimensions, for any value of w and h # 2d.imageData.create2.round . In other words, while user agents may round the arguments of these methods so that they map to device pixel boundaries, any rounding performed must be performed consistently for all of the createImageData(), getImageData() and putImageData() operations.
</quote>

The thrust seems to be that get, put, and create must all consistently round points and dimensions to device coordinates. Then it says:

<quote>
Note: Due to the lossy nature of converting to and from premultiplied alpha color values, pixels that have just been set using putImageData() might be returned to an equivalent getImageData() as different values.
</quote>
Comment 4 noel gordon 2011-12-18 21:36:13 PST
Perhaps file a W3C bug and ask Hixie for clarification.  Failing that, what does Firefox do, or IE9/10?  I believe they round-trip get/put just fine.  Maybe run the round-trip test on those browsers to look at the web-compat story?  I don't see why we should drop round-trip support.
Comment 5 Brent Fulgham 2022-07-01 16:48:18 PDT
This test case appears to work properly (some 10+ years later!)