2 <title>Test ImageBitmap
</title>
4 <script src=
"/tests/SimpleTest/SimpleTest.js"></script>
5 <link rel=
"stylesheet" href=
"/tests/SimpleTest/test.css">
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>
11 <canvas id=
"c1" class=
"output" width=
"128" height=
"128"></canvas>
12 <canvas id=
"c2" width=
"128" height=
"128"></canvas>
14 <script src=
"imagebitmap_bug1239300.js"></script>
15 <script src=
"imagebitmap_bug1239752.js"></script>
16 <script type=
"text/javascript">
18 SimpleTest
.waitForExplicitFinish();
21 * [isPixel description]
22 * @param {[type]} ctx : canvas context
23 * @param {[type]} x : pixel x coordinate
24 * @param {[type]} y : pixel y coordinate
25 * @param {[type]} c : a rgba color code
26 * @param {[type]} d : error duration
29 function isPixel(ctx
, x
, y
, c
, d
) {
30 var pos
= x
+ "," + y
;
31 var color
= c
[0] + "," + c
[1] + "," + c
[2] + "," + c
[3];
32 var pixel
= ctx
.getImageData(x
, y
, 1, 1);
33 var pr
= pixel
.data
[0],
37 ok(c
[0]-d
<= pr
&& pr
<= c
[0]+d
&&
38 c
[1]-d
<= pg
&& pg
<= c
[1]+d
&&
39 c
[2]-d
<= pb
&& pb
<= c
[2]+d
&&
40 c
[3]-d
<= pa
&& pa
<= c
[3]+d
,
41 "pixel "+pos
+" of "+ctx
.canvas
.id
+" is "+pr
+","+pg
+","+pb
+","+pa
+"; expected "+color
+" +/- "+d
);
45 {'rect': [0, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [255, 0, 0, 255], 5]]},
46 {'rect': [128, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [0, 255, 0, 255], 5]]},
47 {'rect': [230, 230, 128, 128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5],
48 [100, 100, [0, 0, 0, 0], 5]]},
49 {'rect': [-64, -64, 512, 512], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 0, 0, 0], 5],
50 [100, 100, [255, 0, 0, 255], 5]]},
51 {'rect': [128, 128, -128, -128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5]]},
52 {'rect': [0, 0, 256, 256], 'draw': [0, 128, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 255, 0, 255], 5]]},
55 var canvas
, ctx
, ctx2
, completedImage
;
58 ok(false, "Promise failure: " + ex
);
62 var resolver
, bitmaps
= [], image
= new Image();
64 image
.src
= 'image_rgrg-256x256.png';
65 var promise
= new Promise(function (arg
) { resolver
= arg
; });
67 function createBitmap(def
) {
68 return createImageBitmap(image
, def
.rect
[0], def
.rect
[1], def
.rect
[2], def
.rect
[3])
69 .then(function (bitmap
) { def
.bitmap
= bitmap
; }, failed
);
72 image
.onload = function() {
73 completedImage
= image
;
74 resolver(Promise
.all(TEST_BITMAPS
.map(createBitmap
)));
77 function testPixel(test
) {
78 isPixel(ctx
, test
[0], test
[1], test
[2], test
[3]);
81 return promise
.then(function() {
82 TEST_BITMAPS
.forEach(function (test
) {
83 if (!test
.bitmap
) { return; }
84 ctx
.clearRect(0, 0, canvas
.width
, canvas
.height
);
85 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]);
86 test
.test
.forEach(testPixel
);
87 is(test
.bitmap
.width
, Math
.abs(test
.rect
[2]), "Bitmap has correct width " + test
.bitmap
.width
);
88 is(test
.bitmap
.height
, Math
.abs(test
.rect
[3]), "Bitmap has correct height " + test
.bitmap
.height
);
93 function testSources() {
94 ctx
.fillStyle
="#00FF00";
95 ctx
.fillRect(0, 0, 128, 128);
97 function check(bitmap
) {
98 ctx2
.clearRect(0, 0, 128, 128);
99 ctx2
.drawImage(bitmap
, 0, 0);
100 isPixel(ctx2
, 0, 0, [0, 255, 0, 255], 5);
103 function getPNGBlobBitmapPromise() {
104 return new Promise(function(resolve
, reject
) {
105 canvas
.toBlob(function(blob
) {
106 resolve(createImageBitmap(blob
));
111 function getJPGBlobBitmapPromise() {
112 return new Promise(function(resolve
, reject
) {
113 canvas
.toBlob(function(blob
) {
114 resolve(createImageBitmap(blob
));
115 }, "image/jpeg", 0.95)
120 createImageBitmap(document
.getElementById('image')).then(check
, failed
), // HTMLImageElement
121 createImageBitmap(ctx
).then(check
, failed
), // CanvasRenderingContext2D
122 createImageBitmap(canvas
).then(check
, failed
), // HTMLCanvasElement
123 createImageBitmap(ctx
).then(function (bitmap
) { return createImageBitmap(bitmap
).then(check
, failed
); }, failed
), // ImageBitmap
124 createImageBitmap(document
.getElementById('video'), 140, 0, 20, 20).then(check
, failed
), // HTMLVideoElement
125 createImageBitmap(ctx
.getImageData(0, 0, 128, 128)).then(check
, failed
), // ImageData
126 getPNGBlobBitmapPromise().then(check
, failed
), // PNG blob
127 getJPGBlobBitmapPromise().then(check
, failed
), // JPEG blob
131 function promiseThrows(p
, name
) {
133 return p
.then(function() { didThrow
= false; },
134 function() { didThrow
= true; })
135 .then(function() { ok(didThrow
, name
); });
138 function testExceptions() {
140 function createImageBitmapWithNeuturedImageData() {
141 return new Promise(function(resolve
, reject
) {
142 var tempImage
= document
.createElement('img');
143 tempImage
.src
= 'image_rgrg-256x256.png';
144 tempImage
.onload = function() {
145 var tempCanvas
= document
.createElement('canvas');
146 var tempCtx
= tempCanvas
.getContext('2d');
147 tempCanvas
.with = tempImage
.naturalWidth
;
148 tempCanvas
.height
= tempImage
.naturalHeight
;
149 tempCtx
.drawImage(tempImage
, 0, 0);
150 var tempWorker
= new Worker("test_imagebitmap_on_worker.js");
151 var imageData
= tempCtx
.getImageData(0, 0, tempImage
.naturalWidth
, tempImage
.naturalHeight
);
152 tempWorker
.postMessage(imageData
.data
.buffer
, [imageData
.data
.buffer
]);
153 tempWorker
.terminate();
155 ok(!imageData
.data
.length
, "Get a neutured ImageData.");
156 resolve(createImageBitmap(imageData
));
161 function createImageBitmapWithCorruptedBlob() {
162 return new Promise(function(resolve
, reject
) {
163 var xhr
= new XMLHttpRequest();
164 xhr
.open("GET", "image_error-early.png");
165 xhr
.responseType
= "blob";//force the HTTP response, response-type header to be blob
166 xhr
.onload = function()
168 ok(xhr
.response
, "Get a corrupted blob");
169 resolve(createImageBitmap(xhr
.response
));
175 function createImageBitmapWithNonImageFile() {
176 return new Promise(function(resolve
, reject
) {
177 var xhr
= new XMLHttpRequest();
178 xhr
.open("GET", "test_imagebitmap_on_worker.js");
179 xhr
.responseType
= "blob";//force the HTTP response, response-type header to be blob
180 xhr
.onload = function()
182 ok(xhr
.response
, "Get a non-image blob");
183 resolve(createImageBitmap(xhr
.response
));
190 promiseThrows(createImageBitmap(new Image()), 'createImageBitmap should throw with unloaded image'),
191 promiseThrows(createImageBitmap(completedImage
, 0, 0, 0, 0), 'createImageBitmap should throw with 0 width/height'),
192 promiseThrows(createImageBitmap(null), 'createImageBitmap should throw with null source'),
193 promiseThrows(createImageBitmapWithNeuturedImageData(), "createImageBitmap should throw with neutured ImageData"),
194 promiseThrows(createImageBitmapWithCorruptedBlob(), "createImageBitmap should throw with corrupted blob"),
195 promiseThrows(createImageBitmapWithNonImageFile(), "createImageBitmap should throw with non-image blob"),
199 function testSecurityErrors() {
201 function getUncleanImagePromise() {
202 return new Promise(function(resolve
, reject
) {
203 var uncleanImage
= document
.createElement('img');
205 uncleanImage
.onload = function() {
206 resolve(createImageBitmap(uncleanImage
));
209 uncleanImage
.onerror = function() {
213 uncleanImage
.src
= "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
217 function getUncleanVideoPromise() {
218 return new Promise(function(resolve
, reject
) {
219 var uncleanVideo
= document
.createElement('video');
221 uncleanVideo
.onloadeddata = function() {
222 resolve(createImageBitmap(uncleanVideo
));
225 uncleanVideo
.onerror = function() {
229 uncleanVideo
.src
= "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.webm&type=video/webm";
234 function getTaintedCanvasPromise() {
235 return new Promise(function(resolve
, reject
) {
236 var uncleanImage
= document
.createElement('img');
238 uncleanImage
.onload = function() {
239 var taintedCanvas
= document
.createElement('canvas');
240 var taintedCtx
= taintedCanvas
.getContext('2d');
241 taintedCtx
.drawImage(uncleanImage
, 0, 0);
242 resolve(createImageBitmap(taintedCanvas
));
245 uncleanImage
.onerror = function() {
249 uncleanImage
.src
= "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
253 function getTaintedCanvasRenderingContex2dPromise() {
254 return new Promise(function(resolve
, reject
) {
255 var uncleanImage
= document
.createElement('img');
257 uncleanImage
.onload = function() {
258 var taintedCanvas
= document
.createElement('canvas');
259 var taintedCtx
= taintedCanvas
.getContext('2d');
260 taintedCtx
.drawImage(uncleanImage
, 0, 0);
261 resolve(createImageBitmap(taintedCtx
));
264 uncleanImage
.onerror = function() {
268 uncleanImage
.src
= "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
272 function checkPromiseFailedWithSecurityError(p
) {
273 return p
.then(imageBitmap
=> {
274 ok(!!imageBitmap
, "ImageBitmaps are always created");
275 const context
= document
.createElement("canvas").getContext("2d");
276 context
.drawImage(imageBitmap
, 0, 0);
278 context
.getImageData(0, 0, 1, 1);
279 ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully.");
281 if (ex
== "SecurityError: The operation is insecure.") {
282 ok(true, ex
.message
);
285 ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex
.message
);
292 checkPromiseFailedWithSecurityError(getUncleanImagePromise()),
293 checkPromiseFailedWithSecurityError(getUncleanVideoPromise()),
294 checkPromiseFailedWithSecurityError(getTaintedCanvasPromise()),
295 checkPromiseFailedWithSecurityError(getTaintedCanvasRenderingContex2dPromise()),
299 function testCreatePattern() {
301 var promise
= new Promise(function (arg
) { resolve
= arg
; });
304 [0, 0, [255, 0, 0, 255], 1],
305 [128, 128, [255, 0, 0, 255], 1],
306 [256, 256, [255, 0, 0, 255], 1],
307 [384, 0, [0, 255, 0, 255], 1],
308 [0, 384, [0, 255, 0, 255], 1],
311 var patternCanvas
= document
.createElement('canvas');
312 patternCanvas
.width
= "512";
313 patternCanvas
.height
= "512";
314 var patternCtx
= patternCanvas
.getContext('2d');
316 var image
= new Image();
317 image
.src
= 'image_rgrg-256x256.png';
318 image
.onload = function() {
319 var p
= createImageBitmap(image
);
320 p
.then(function(bitmap
) {
321 patternCtx
.rect(0, 0, 512, 512);
322 patternCtx
.fillStyle
= patternCtx
.createPattern(bitmap
, "repeat");
324 document
.body
.appendChild(patternCanvas
);
329 return promise
.then(function() {
330 TEST_PATTERN
.forEach(function(test
) {
331 isPixel(patternCtx
, test
[0], test
[1], test
[2], test
[3]);
337 function runTests() {
338 canvas
= document
.getElementById('c1');
339 ctx
= canvas
.getContext('2d');
340 ctx2
= document
.getElementById('c2').getContext('2d');
343 .then(testCreatePattern
)
345 .then(testExceptions
)
346 .then(testSecurityErrors
)
347 .then(testBug1239300
)
348 .then(testBug1239752
)
349 .then(SimpleTest
.finish
, function(ev
) { failed(ev
); SimpleTest
.finish(); });
352 addLoadEvent(runTests
);