| <!DOCTYPE html> |
| <html> |
| <body> |
| <canvas id="canvas" width="3" height="2"></canvas> |
| <script src="../../resources/js-test.js"></script> |
| <script> |
| jsTestIsAsync = true; |
| var worker = new Worker('./resources/canvas-ImageBitmap-structured-clone.js'); |
| |
| description("Tests that ImageBitmap supports structured clone and that the pixel data survives the trip between main <--> worker"); |
| |
| function shouldNotBeCalled(e) { |
| testFailed("promise rejected." + e); |
| finishJSTest(); |
| } |
| |
| function compareImageData(data1, data2) |
| { |
| if (data1.length != data2.length) { |
| testFailed("The two image have different dimensions"); |
| return; |
| } |
| for (var i = 0; i < data1.length; i++) { |
| if ((i % 4 != 3 && Math.abs(data1[i] - data2[i]) > 5) || |
| (i % 4 == 3 && data1[i] != data2[i])) { |
| testFailed("The ImageBitmap pixel data did not survive the round trip"); |
| return; |
| } |
| } |
| testPassed("The ImageBitmap pixel data survives the round trip"); |
| } |
| |
| function checkImageBitmap1() { |
| shouldBe("bitmapWidth", "imageWidth1"); |
| shouldBe("bitmapHeight", "imageHeight1"); |
| |
| // newImage is not necessary the same as imageData because of |
| // multiplying and dividing by alpha during the round trip, but |
| // they should be close. |
| // The alpha channel should be exactly the same. |
| compareImageData(newImage.data, imageData1); |
| } |
| |
| function checkImageBitmap2() { |
| shouldBe("bitmapWidth", "imageWidth2"); |
| shouldBe("bitmapHeight", "imageHeight2"); |
| |
| compareImageData(newImage.data, imageData2); |
| } |
| |
| function postToWorker(message, transferable) { |
| return new Promise((resolve, reject) => { |
| function onMessage(e) { |
| resolve(e.data); |
| worker.removeEventListener("message", onMessage); |
| } |
| worker.postMessage(message, transferable); |
| worker.addEventListener("message", onMessage); |
| }); |
| } |
| |
| function getNewImageDataFromImageBitmap(newImageBitmap) |
| { |
| bitmapWidth = newImageBitmap.width; |
| bitmapHeight = newImageBitmap.height; |
| context.clearRect(0, 0, imageWidth1, imageHeight1); |
| context.drawImage(newImageBitmap, 0, 0, bitmapWidth, bitmapHeight); |
| newImage = context.getImageData(0, 0, bitmapWidth, bitmapHeight); |
| } |
| |
| var imageWidth1 = 3; |
| var imageHeight1 = 2; |
| var imageWidth2 = 1; |
| var imageHeight2 = 1; |
| var bitmapWidth; |
| var bitmapHeight; |
| var imageBitmap1; |
| var imageBitmap2; |
| var newImage; |
| var imageData1; |
| var imageData2; |
| var image1 = new ImageData(new Uint8ClampedArray( |
| [255, 0, 0, 255, |
| 0, 255, 0, 255, |
| 255, 255, 255, 127, |
| 0, 0, 0, 64, |
| 12, 34, 56, 64, |
| 12, 34, 56, 127]), |
| imageWidth1, imageHeight1); |
| var image2 = new ImageData(new Uint8ClampedArray([255, 128, 64, 127]), imageWidth2, imageHeight2); |
| var context = document.getElementById("canvas").getContext("2d"); |
| |
| var p1 = createImageBitmap(image1).then(function(image) {imageBitmap1 = image}); |
| var p2 = createImageBitmap(image2, {imageOrientation: "none", premultiplyAlpha: "none"}).then(function(image) {imageBitmap2 = image}); |
| Promise.all([p1, p2]).then(function() { |
| getNewImageDataFromImageBitmap(imageBitmap1); |
| imageData1 = newImage.data; |
| getNewImageDataFromImageBitmap(imageBitmap2); |
| imageData2 = newImage.data; |
| |
| bitmapWidth = imageBitmap1.width; |
| bitmapHeight = imageBitmap1.height; |
| shouldBe("bitmapWidth", "imageWidth1"); |
| shouldBe("bitmapHeight", "imageHeight1"); |
| |
| var replyPromise = postToWorker(imageBitmap1); |
| |
| // Structured cloning should not neuter the source ImageBitmap |
| bitmapWidth = imageBitmap1.width; |
| bitmapHeight = imageBitmap1.height; |
| shouldBe("bitmapWidth", "imageWidth1"); |
| shouldBe("bitmapHeight", "imageHeight1"); |
| |
| return replyPromise.then(reply => { |
| getNewImageDataFromImageBitmap(reply); |
| checkImageBitmap1(); |
| }); |
| }).then(function() { |
| var replyPromise = postToWorker(imageBitmap1, [imageBitmap1]); |
| |
| // Transfer the ImageBitmap should neuter it |
| bitmapWidth = imageBitmap1.width; |
| bitmapHeight = imageBitmap1.height; |
| shouldBe("bitmapWidth", "0"); |
| shouldBe("bitmapHeight", "0"); |
| |
| return replyPromise.then(reply => { |
| getNewImageDataFromImageBitmap(reply); |
| checkImageBitmap1(); |
| }); |
| }).then(function() { |
| var replyPromise = postToWorker(imageBitmap2); |
| |
| // Structured cloning should not neuter the source ImageBitmap |
| bitmapWidth = imageBitmap2.width; |
| bitmapHeight = imageBitmap2.height; |
| shouldBe("bitmapWidth", "imageWidth2"); |
| shouldBe("bitmapHeight", "imageHeight2"); |
| |
| return replyPromise.then(reply => { |
| getNewImageDataFromImageBitmap(reply); |
| checkImageBitmap2(); |
| }); |
| }).then(finishJSTest, shouldNotBeCalled); |
| </script> |
| </body> |
| </html> |