| <!DOCTYPE HTML> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script> |
| |
| var imageBitmap; |
| |
| // Image sources to be passed to createImageBitmap |
| var canvas; |
| var image; |
| var imageBitmap; |
| var imageData; |
| var blob; |
| |
| var imageWidth = 20; |
| var imageHeight = 20; |
| |
| // createImageBitmap from canvas |
| canvas = document.createElement("canvas"); |
| canvas.width = imageWidth; |
| canvas.height = imageHeight; |
| var ctx = canvas.getContext("2d"); |
| drawPattern(ctx); |
| var t_canvas = async_test("Testing createImageBitmap from canvas."); |
| var runCanvasTests = t_canvas.step_func(function() { |
| return runTests(t_canvas, canvas); |
| }); |
| runCanvasTests(); |
| |
| // createImageBitmap from image and imagebitmap |
| image = new Image(); |
| var t_image = async_test("Testing createImageBitmap from image."); |
| image.onload = t_image.step_func(function() { |
| async_test(t => { |
| createImageBitmap(image).then(function(bitmap) { |
| imageBitmap = bitmap; |
| var runImageBitmapTests = t.step_func(function() { |
| return runTests(t, imageBitmap); |
| }); |
| runImageBitmapTests(); |
| t.done(); |
| }, function() { |
| promiseRejectedUnexpectedly(); |
| }); |
| }, "Testing createImageBitmap from imagebitmap."); |
| return runTests(t_image, image); |
| }); |
| image.src = canvas.toDataURL(); |
| |
| // createImageBitmap from imagedata |
| imageData = ctx.getImageData(0, 0, 20, 20); |
| var t_imageData = async_test("Testing createImageBitmap from ImageData."); |
| var runImageDataTests = t_imageData.step_func(function() { |
| return runTests(t_imageData, imageData); |
| }); |
| runImageDataTests(); |
| |
| // createImageBitmap from blob |
| var xhr = new XMLHttpRequest(); |
| xhr.open("GET", 'resources/pattern.png'); |
| xhr.responseType = 'blob'; |
| xhr.send(); |
| var t_blob = async_test("Testing createImageBitmap from blob."); |
| xhr.onload = t_blob.step_func(function() { |
| blob = xhr.response; |
| return runTests(t_blob, blob); |
| }); |
| |
| // createImageBitmap from video |
| var video = document.createElement("video"); |
| var t_video = async_test('Testing createImageBitmap from video.'); |
| video.addEventListener("canplaythrough", |
| t_video.step_func(function() { |
| return runTests(t_video, video); |
| }), false); |
| video.preload = "auto"; |
| video.src = "resources/pattern.ogv"; |
| |
| |
| function runTests(t, element) { |
| imageBitmaps = {}; |
| var p1 = createImageBitmap(element).then(function (image) { |
| imageBitmaps.noCrop = image }); |
| var p2 = createImageBitmap(element, 0, 0, 10, 10).then( |
| function (image) { imageBitmaps.crop = image }); |
| var p3 = createImageBitmap(element, 5, 5, 10, 10).then( |
| function (image) { imageBitmaps.cropCenter = image }); |
| var p4 = createImageBitmap(element, 10, 10, 10, 10).then( |
| function (image) { imageBitmaps.cropRight = image }); |
| var p5 = createImageBitmap(element, -10, -10, 60, 60).then( |
| function (image) { imageBitmaps.overCrop = image }); |
| var p6 = createImageBitmap(element, 10, 10, 50, 50).then( |
| function (image) { imageBitmaps.overCropRight = image }); |
| var p7 = createImageBitmap(element, 10, 10, -10, -10).then( |
| function (image) { imageBitmaps.negativeCrop = image }); |
| var p8 = createImageBitmap(element, -30, -30, 30, 30).then( |
| function (image) { imageBitmaps.blankImage1 = image }); |
| var p9 = createImageBitmap(element, 40, 30, 30, 30).then( |
| function (image) { imageBitmaps.blankImage2 = image }); |
| |
| return Promise.all([p1, p2, p3, p4, p5, p6, p7, p8, p9]).then( |
| t.step_func_done(function() { |
| |
| var acanvas = document.createElement("canvas"); |
| acanvas.setAttribute("width", "50"); |
| acanvas.setAttribute("height", "50"); |
| var actx = acanvas.getContext("2d"); |
| |
| var tolerance = 0; |
| // Strictly the same under software rendering, but significantly |
| // different on GPU. |
| if (jsWrapperClass(element) == "HTMLVideoElement") |
| tolerance = 80; |
| |
| checkNoCrop(actx, imageBitmaps.noCrop, tolerance); |
| checkCrop(actx, imageBitmaps.crop, tolerance); |
| checkCropCenter(actx, imageBitmaps.cropCenter, tolerance); |
| checkCropRight(actx, imageBitmaps.cropRight, tolerance); |
| checkOverCrop(actx, imageBitmaps.overCrop, tolerance); |
| checkOverCropRight(actx, imageBitmaps.overCropRight, tolerance); |
| checkCrop(actx, imageBitmaps.negativeCrop, tolerance); |
| checkBlankImageBitmap(actx, imageBitmaps.blankImage1, tolerance); |
| checkBlankImageBitmap(actx, imageBitmaps.blankImage2, tolerance); |
| |
| async_test(t => { |
| createImageBitmap(element, 0, 0, Math.pow(10, 6), |
| Math.pow(10, 6)).then(function() { |
| promiseResolvedUnexpectedly( |
| 'Asking for a huge ImageBitmap unexpectedly resolved.'); |
| t.done(); |
| }, function() { |
| t.done(); |
| }); |
| }, "Asking for a huge ImageBitmap from " + jsWrapperClass(element) + " should be rejected."); |
| |
| }), t.step_func_done(function() { |
| promiseRejectedUnexpectedly(); |
| })); |
| } |
| |
| //---------------------------- Helper functions -------------------------------- |
| |
| function jsWrapperClass(node) |
| { |
| // returns the ClassName of node |
| if (!node) |
| return "[null]"; |
| var string = Object.prototype.toString.apply(node); |
| |
| // string will be of the form [object ClassName] |
| return string.substr(8, string.length - 9); |
| } |
| |
| function shouldBeType(expression, className) |
| { |
| assert_equals(jsWrapperClass(expression), className); |
| } |
| |
| function promiseRejectedUnexpectedly() { |
| assert_true(false, "createImageBitmap promise rejected."); |
| } |
| |
| function promiseResolvedUnexpectedly(message) { |
| assert_true(false, message); |
| } |
| |
| var redPixel = [255, 0, 0, 255]; |
| var greenPixel = [0, 255, 0, 255]; |
| var bluePixel = [0, 0, 255, 255]; |
| var blackPixel = [0, 0, 0, 255]; |
| var transparentPixel = [0, 0, 0, 0]; |
| |
| function checkPixelsRef(refPixel, ctx, pixels, tolerance) { |
| for (var i = 0; i < pixels.length; i++) { |
| d = ctx.getImageData(pixels[i][0], pixels[i][1], 1, 1).data; |
| assert_array_approx_equals(d, refPixel, tolerance); |
| } |
| } |
| |
| function checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance) { |
| checkPixelsRef(redPixel, ctx, redPixels, tolerance); |
| checkPixelsRef(greenPixel, ctx, greenPixels, tolerance); |
| checkPixelsRef(bluePixel, ctx, bluePixels, tolerance); |
| checkPixelsRef(blackPixel, ctx, blackPixels, tolerance); |
| checkPixelsRef(transparentPixel, ctx, transparentPixels, tolerance); |
| } |
| |
| function clearContext(ctx, width, height) { |
| ctx.clearRect(0, 0, width, height); |
| } |
| |
| function drawPattern(ctx) { |
| // Draw a four-color pattern |
| ctx.beginPath(); |
| ctx.fillStyle = "rgb(255, 0, 0)"; |
| ctx.fillRect(0, 0, 10, 10); |
| ctx.fillStyle = "rgb(0, 255, 0)"; |
| ctx.fillRect(10, 0, 10, 10); |
| ctx.fillStyle = "rgb(0, 0, 255)"; |
| ctx.fillRect(0, 10, 10, 10); |
| ctx.fillStyle = "rgb(0, 0, 0)"; |
| ctx.fillRect(10, 10, 10, 10); |
| } |
| |
| function checkNoCrop(ctx, imageBitmap, tolerance) { |
| shouldBeType(imageBitmap, "ImageBitmap"); |
| assert_equals(imageBitmap.width, 20); |
| assert_equals(imageBitmap.height, 20); |
| |
| // should be drawn to (0, 0), (20, 20) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0); |
| redPixels = [[9, 9]]; |
| greenPixels = [[11, 9]]; |
| bluePixels = [[9, 11]];; |
| blackPixels = [[11, 11], [19, 19]]; |
| transparentPixels = [[1, 21], [21, 1], [21, 21]]; |
| checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance); |
| |
| // shrunk to (0, 0), (10, 10) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0, 10, 10); |
| redPixels = [[4, 4]]; |
| greenPixels = [[6, 4]]; |
| bluePixels = [[4, 6]]; |
| blackPixels = [[6, 6], [9, 9]]; |
| transparentPixels = [[1, 11], [11, 1], [11, 11]]; |
| checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance); |
| |
| // shrunk to (10, 10), (20, 20) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 10, 10, 10, 10); |
| redPixels = [[14, 14]]; |
| greenPixels = [[16, 14]]; |
| bluePixels = [[14, 16]]; |
| blackPixels = [[16, 16], [19, 19]]; |
| transparentPixels = [[11, 21], [21, 11], [21, 21]]; |
| checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance); |
| |
| // black should be drawn to (10, 10), (20, 20) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 10, 10, 10, 10, 10, 10, 10, 10); |
| blackPixels = [[11, 11], [19, 19]]; |
| transparentPixels = [[9, 9], [1, 21], [21, 1], [21, 21]]; |
| checkPixels(ctx, [], [], [], blackPixels, transparentPixels, tolerance); |
| } |
| |
| function checkCrop(ctx, imageBitmap, tolerance) { |
| shouldBeType(imageBitmap, "ImageBitmap"); |
| assert_equals(imageBitmap.width, 10); |
| assert_equals(imageBitmap.height, 10); |
| |
| // red should be drawn to (0, 0), (10, 10) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0); |
| redPixels = [[0, 1], [1, 0], [1, 1], [9, 9]]; |
| transparentPixels = [[12, 12], [1, 12], [12, 1]]; |
| checkPixels(ctx, redPixels, [], [], [], transparentPixels, tolerance); |
| |
| // red should be drawn to (0, 0), (20, 20) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0, 20, 20); |
| redPixels = [[1, 1], [18, 18]]; |
| transparentPixels = [[22, 22], [1, 22], [22, 1]]; |
| checkPixels(ctx, redPixels, [], [], [], transparentPixels, tolerance); |
| } |
| |
| function checkCropCenter(ctx, imageBitmap, tolerance) { |
| shouldBeType(imageBitmap, "ImageBitmap"); |
| assert_equals(imageBitmap.width, 10); |
| assert_equals(imageBitmap.height, 10); |
| |
| // should be drawn to (0, 0), (10, 10) with all four colors |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0); |
| redPixels = [[4, 4]]; |
| greenPixels = [[6, 4]]; |
| bluePixels = [[4, 6]]; |
| blackPixels = [[6, 6], [9, 9]]; |
| transparentPixels = [[11, 11], [1, 11], [11, 1]]; |
| checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance); |
| |
| // should be drawn to (0, 0), (20, 20) with all four colors |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0, 20, 20); |
| redPixels = [[8, 8]]; |
| greenPixels = [[11, 8]]; |
| bluePixels = [[8, 11]]; |
| blackPixels = [[11, 11], [18, 18]]; |
| transparentPixels = [[22, 22], [1, 21], [21, 1]]; |
| checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance); |
| } |
| |
| function checkCropRight(ctx, imageBitmap, tolerance) { |
| shouldBeType(imageBitmap, "ImageBitmap"); |
| assert_equals(imageBitmap.width, 10); |
| assert_equals(imageBitmap.height, 10); |
| |
| // black should be drawn to (0, 0), (10, 10) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0); |
| blackPixels = [[1, 1], [9, 9]]; |
| transparentPixels = [[11, 11], [1, 11], [11, 1]]; |
| checkPixels(ctx, [], [], [], blackPixels, transparentPixels, tolerance); |
| } |
| |
| function checkOverCrop(ctx, imageBitmap, tolerance) { |
| shouldBeType(imageBitmap, "ImageBitmap"); |
| assert_equals(imageBitmap.width, 20); |
| assert_equals(imageBitmap.height, 20); |
| |
| // should be drawn to (0, 0), (20, 20) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0); |
| redPixels = [[9, 9]]; |
| greenPixels = [[11, 9]]; |
| bluePixels = [[9, 11]]; |
| blackPixels = [[11, 11], [19, 19]]; |
| transparentPixels = [[1, 21], [21, 1], [21, 21]]; |
| checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance); |
| |
| // shrunk to (0, 0), (10, 10) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0, 10, 10); |
| redPixels = [[4, 4]]; |
| greenPixels = [[6, 4]]; |
| bluePixels = [[4, 6]]; |
| blackPixels = [[6, 6], [9, 9]]; |
| transparentPixels = [[1, 11], [11, 1], [11, 11]]; |
| checkPixels(ctx, redPixels, greenPixels, bluePixels, blackPixels, |
| transparentPixels, tolerance); |
| } |
| |
| function checkOverCropRight(ctx, imageBitmap, tolerance) { |
| assert_equals(imageBitmap.width, 10); |
| assert_equals(imageBitmap.height, 10); |
| |
| // black should be drawn to (0, 0), (10, 10) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0); |
| blackPixels = [[1, 1], [9, 9]]; |
| transparentPixels = [[11, 11], [1, 11], [11, 1]]; |
| checkPixels(ctx, [], [], [], blackPixels, transparentPixels, tolerance); |
| |
| // black should be drawn to (0, 0), (4, 4) |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0, 4, 4); |
| blackPixels = [[1, 1], [3, 3]]; |
| transparentPixels = [[5, 5], [1, 5], [5, 1]]; |
| checkPixels(ctx, [], [], [], blackPixels, transparentPixels, tolerance); |
| |
| // nothing should be drawn |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 10, 10, 20, 20, 0, 0, 20, 20); |
| transparentPixels = [[1, 1], [3, 3], [5, 5], [1, 5], [5, 1]]; |
| checkPixels(ctx, [], [], [], [], transparentPixels, tolerance); |
| } |
| |
| function checkBlankImageBitmap(ctx, imageBitmap, tolerance) { |
| shouldBeType(imageBitmap, "ImageBitmap"); |
| |
| clearContext(ctx, 50, 50); |
| ctx.drawImage(imageBitmap, 0, 0); |
| transparentPixels = [[1, 1], [9, 9], [11, 11], [21, 21]]; |
| checkPixels(ctx, [], [], [], [], transparentPixels, tolerance); |
| } |
| |
| </script> |
| </body> |
| </html> |