test_imagebitmap.html (13040B)
1 <!DOCTYPE HTML> 2 <title>Test ImageBitmap</title> 3 <meta charset="utf-8"> 4 <script src="/tests/SimpleTest/SimpleTest.js"></script> 5 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> 6 <body> 7 8 <img src="image_anim-gr.gif" id="image" class="resource"> 9 <video width="320" height="240" src="http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.webm&type=video/webm&cors=anonymous" id="video" crossOrigin="anonymous" autoplay></video> 10 11 <canvas id="c1" class="output" width="128" height="128"></canvas> 12 <canvas id="c2" width="128" height="128"></canvas> 13 14 <script src="imagebitmap_bug1239300.js"></script> 15 <script src="imagebitmap_bug1239752.js"></script> 16 <script type="text/javascript"> 17 18 SimpleTest.waitForExplicitFinish(); 19 20 /** 21 * [isPixel description] 22 * 23 * @param {[type]} ctx : canvas context 24 * @param {[type]} x : pixel x coordinate 25 * @param {[type]} y : pixel y coordinate 26 * @param {[type]} c : a rgba color code 27 * @param {[type]} d : error duration 28 * @return {Promise} 29 */ 30 function isPixel(ctx, x, y, c, d) { 31 var pos = x + "," + y; 32 var color = c[0] + "," + c[1] + "," + c[2] + "," + c[3]; 33 var pixel = ctx.getImageData(x, y, 1, 1); 34 var pr = pixel.data[0], 35 pg = pixel.data[1], 36 pb = pixel.data[2], 37 pa = pixel.data[3]; 38 ok(c[0]-d <= pr && pr <= c[0]+d && 39 c[1]-d <= pg && pg <= c[1]+d && 40 c[2]-d <= pb && pb <= c[2]+d && 41 c[3]-d <= pa && pa <= c[3]+d, 42 "pixel "+pos+" of "+ctx.canvas.id+" is "+pr+","+pg+","+pb+","+pa+"; expected "+color+" +/- "+d); 43 } 44 45 var TEST_BITMAPS = [ 46 {'rect': [0, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [255, 0, 0, 255], 5]]}, 47 {'rect': [128, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [0, 255, 0, 255], 5]]}, 48 {'rect': [230, 230, 128, 128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5], 49 [100, 100, [0, 0, 0, 0], 5]]}, 50 {'rect': [-64, -64, 512, 512], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 0, 0, 0], 5], 51 [100, 100, [255, 0, 0, 255], 5]]}, 52 {'rect': [128, 128, -128, -128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5]]}, 53 {'rect': [0, 0, 256, 256], 'draw': [0, 128, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 255, 0, 255], 5]]}, 54 ]; 55 56 var canvas, ctx, ctx2, completedImage; 57 58 function failed(ex) { 59 ok(false, "Promise failure: " + ex); 60 } 61 62 function testDraw() { 63 var resolver, bitmaps = [], image = new Image(); 64 65 image.src = 'image_rgrg-256x256.png'; 66 var promise = new Promise(function (arg) { resolver = arg; }); 67 68 function createBitmap(def) { 69 return createImageBitmap(image, def.rect[0], def.rect[1], def.rect[2], def.rect[3]) 70 .then(function (bitmap) { def.bitmap = bitmap; }, failed); 71 }; 72 73 image.onload = function() { 74 completedImage = image; 75 resolver(Promise.all(TEST_BITMAPS.map(createBitmap))); 76 }; 77 78 function testPixel(test) { 79 isPixel(ctx, test[0], test[1], test[2], test[3]); 80 }; 81 82 return promise.then(function() { 83 TEST_BITMAPS.forEach(function (test) { 84 if (!test.bitmap) { return; } 85 ctx.clearRect(0, 0, canvas.width, canvas.height); 86 ctx.drawImage(test.bitmap, test.draw[0], test.draw[1], test.draw[2], test.draw[3], test.draw[4], test.draw[5], test.draw[6], test.draw[7]); 87 test.test.forEach(testPixel); 88 is(test.bitmap.width, Math.abs(test.rect[2]), "Bitmap has correct width " + test.bitmap.width); 89 is(test.bitmap.height, Math.abs(test.rect[3]), "Bitmap has correct height " + test.bitmap.height); 90 }); 91 }); 92 } 93 94 function testSources() { 95 ctx.fillStyle="#00FF00"; 96 ctx.fillRect(0, 0, 128, 128); 97 98 function check(bitmap) { 99 ctx2.clearRect(0, 0, 128, 128); 100 ctx2.drawImage(bitmap, 0, 0); 101 isPixel(ctx2, 0, 0, [0, 255, 0, 255], 5); 102 }; 103 104 function getPNGBlobBitmapPromise() { 105 return new Promise(function(resolve, reject) { 106 canvas.toBlob(function(blob) { 107 resolve(createImageBitmap(blob)); 108 }) 109 }); 110 } 111 112 function getJPGBlobBitmapPromise() { 113 return new Promise(function(resolve, reject) { 114 canvas.toBlob(function(blob) { 115 resolve(createImageBitmap(blob)); 116 }, "image/jpeg", 0.95) 117 }); 118 } 119 120 return Promise.all([ 121 createImageBitmap(document.getElementById('image')).then(check, failed), // HTMLImageElement 122 createImageBitmap(ctx).then(check, failed), // CanvasRenderingContext2D 123 createImageBitmap(canvas).then(check, failed), // HTMLCanvasElement 124 createImageBitmap(ctx).then(function (bitmap) { return createImageBitmap(bitmap).then(check, failed); }, failed), // ImageBitmap 125 createImageBitmap(document.getElementById('video'), 140, 0, 20, 20).then(check, failed), // HTMLVideoElement 126 createImageBitmap(ctx.getImageData(0, 0, 128, 128)).then(check, failed), // ImageData 127 getPNGBlobBitmapPromise().then(check, failed), // PNG blob 128 getJPGBlobBitmapPromise().then(check, failed), // JPEG blob 129 ]); 130 } 131 132 function promiseThrows(p, name) { 133 var didThrow; 134 return p.then(function() { didThrow = false; }, 135 function() { didThrow = true; }) 136 .then(function() { ok(didThrow, name); }); 137 } 138 139 function testExceptions() { 140 141 function createImageBitmapWithNeuturedImageData() { 142 return new Promise(function(resolve, reject) { 143 var tempImage = document.createElement('img'); 144 tempImage.src = 'image_rgrg-256x256.png'; 145 tempImage.onload = function() { 146 var tempCanvas = document.createElement('canvas'); 147 var tempCtx = tempCanvas.getContext('2d'); 148 tempCanvas.with = tempImage.naturalWidth; 149 tempCanvas.height = tempImage.naturalHeight; 150 tempCtx.drawImage(tempImage, 0, 0); 151 var tempWorker = new Worker("test_imagebitmap_on_worker.js"); 152 var imageData = tempCtx.getImageData(0, 0, tempImage.naturalWidth, tempImage.naturalHeight); 153 tempWorker.postMessage(imageData.data.buffer, [imageData.data.buffer]); 154 tempWorker.terminate(); 155 156 ok(!imageData.data.length, "Get a neutured ImageData."); 157 resolve(createImageBitmap(imageData)); 158 } 159 }); 160 } 161 162 function createImageBitmapWithCorruptedBlob() { 163 return new Promise(function(resolve, reject) { 164 var xhr = new XMLHttpRequest(); 165 xhr.open("GET", "image_error-early.png"); 166 xhr.responseType = "blob";//force the HTTP response, response-type header to be blob 167 xhr.onload = function() 168 { 169 ok(xhr.response, "Get a corrupted blob"); 170 resolve(createImageBitmap(xhr.response)); 171 } 172 xhr.send(); 173 }); 174 } 175 176 function createImageBitmapWithNonImageFile() { 177 return new Promise(function(resolve, reject) { 178 var xhr = new XMLHttpRequest(); 179 xhr.open("GET", "test_imagebitmap_on_worker.js"); 180 xhr.responseType = "blob";//force the HTTP response, response-type header to be blob 181 xhr.onload = function() 182 { 183 ok(xhr.response, "Get a non-image blob"); 184 resolve(createImageBitmap(xhr.response)); 185 } 186 xhr.send(); 187 }); 188 } 189 190 return Promise.all([ 191 promiseThrows(createImageBitmap(new Image()), 'createImageBitmap should throw with unloaded image'), 192 promiseThrows(createImageBitmap(completedImage, 0, 0, 0, 0), 'createImageBitmap should throw with 0 width/height'), 193 promiseThrows(createImageBitmap(null), 'createImageBitmap should throw with null source'), 194 promiseThrows(createImageBitmapWithNeuturedImageData(), "createImageBitmap should throw with neutured ImageData"), 195 promiseThrows(createImageBitmapWithCorruptedBlob(), "createImageBitmap should throw with corrupted blob"), 196 promiseThrows(createImageBitmapWithNonImageFile(), "createImageBitmap should throw with non-image blob"), 197 ]); 198 } 199 200 function testSecurityErrors() { 201 202 function getUncleanImagePromise() { 203 return new Promise(function(resolve, reject) { 204 var uncleanImage = document.createElement('img'); 205 206 uncleanImage.onload = function() { 207 resolve(createImageBitmap(uncleanImage)); 208 } 209 210 uncleanImage.onerror = function() { 211 reject(); 212 } 213 214 uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png"; 215 }); 216 } 217 218 function getUncleanVideoPromise() { 219 return new Promise(function(resolve, reject) { 220 var uncleanVideo = document.createElement('video'); 221 222 uncleanVideo.onloadeddata = function() { 223 resolve(createImageBitmap(uncleanVideo)); 224 } 225 226 uncleanVideo.onerror = function() { 227 reject(); 228 } 229 230 uncleanVideo.src = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.webm&type=video/webm"; 231 uncleanVideo.play(); 232 }); 233 } 234 235 function getTaintedCanvasPromise() { 236 return new Promise(function(resolve, reject) { 237 var uncleanImage = document.createElement('img'); 238 239 uncleanImage.onload = function() { 240 var taintedCanvas = document.createElement('canvas'); 241 var taintedCtx = taintedCanvas.getContext('2d'); 242 taintedCtx.drawImage(uncleanImage, 0, 0); 243 resolve(createImageBitmap(taintedCanvas)); 244 } 245 246 uncleanImage.onerror = function() { 247 reject(); 248 } 249 250 uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png"; 251 }); 252 } 253 254 function getTaintedCanvasRenderingContex2dPromise() { 255 return new Promise(function(resolve, reject) { 256 var uncleanImage = document.createElement('img'); 257 258 uncleanImage.onload = function() { 259 var taintedCanvas = document.createElement('canvas'); 260 var taintedCtx = taintedCanvas.getContext('2d'); 261 taintedCtx.drawImage(uncleanImage, 0, 0); 262 resolve(createImageBitmap(taintedCtx)); 263 } 264 265 uncleanImage.onerror = function() { 266 reject(); 267 } 268 269 uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png"; 270 }); 271 } 272 273 function checkPromiseFailedWithSecurityError(p) { 274 return p.then(imageBitmap => { 275 ok(!!imageBitmap, "ImageBitmaps are always created"); 276 const context = document.createElement("canvas").getContext("2d"); 277 context.drawImage(imageBitmap, 0, 0); 278 try { 279 context.getImageData(0, 0, 1, 1); 280 ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully."); 281 } catch (ex) { 282 if (ex == "SecurityError: The operation is insecure.") { 283 ok(true, ex.message); 284 } 285 else { 286 ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex.message); 287 } 288 } 289 }); 290 } 291 292 return Promise.all([ 293 checkPromiseFailedWithSecurityError(getUncleanImagePromise()), 294 checkPromiseFailedWithSecurityError(getUncleanVideoPromise()), 295 checkPromiseFailedWithSecurityError(getTaintedCanvasPromise()), 296 checkPromiseFailedWithSecurityError(getTaintedCanvasRenderingContex2dPromise()), 297 ]); 298 } 299 300 function testCreatePattern() { 301 var resolve; 302 var promise = new Promise(function (arg) { resolve = arg; }); 303 304 var TEST_PATTERN = [ 305 [0, 0, [255, 0, 0, 255], 1], 306 [128, 128, [255, 0, 0, 255], 1], 307 [256, 256, [255, 0, 0, 255], 1], 308 [384, 0, [0, 255, 0, 255], 1], 309 [0, 384, [0, 255, 0, 255], 1], 310 ]; 311 312 var patternCanvas = document.createElement('canvas'); 313 patternCanvas.width = "512"; 314 patternCanvas.height = "512"; 315 var patternCtx = patternCanvas.getContext('2d'); 316 317 var image = new Image(); 318 image.src = 'image_rgrg-256x256.png'; 319 image.onload = function() { 320 var p = createImageBitmap(image); 321 p.then(function(bitmap) { 322 patternCtx.rect(0, 0, 512, 512); 323 patternCtx.fillStyle = patternCtx.createPattern(bitmap, "repeat"); 324 patternCtx.fill(); 325 document.body.appendChild(patternCanvas); 326 }); 327 resolve(p); 328 } 329 330 return promise.then(function() { 331 TEST_PATTERN.forEach(function(test) { 332 isPixel(patternCtx, test[0], test[1], test[2], test[3]); 333 }); 334 }); 335 } 336 337 338 function runTests() { 339 canvas = document.getElementById('c1'); 340 ctx = canvas.getContext('2d'); 341 ctx2 = document.getElementById('c2').getContext('2d'); 342 343 testDraw() 344 .then(testCreatePattern) 345 .then(testSources) 346 .then(testExceptions) 347 .then(testSecurityErrors) 348 .then(testBug1239300) 349 .then(testBug1239752) 350 .then(SimpleTest.finish, function(ev) { failed(ev); SimpleTest.finish(); }); 351 } 352 353 addLoadEvent(runTests); 354 355 </script> 356 </body>