forked from mirrors/gecko-dev
Backed out changeset 9b8435c1c982 (bug 1860492) Backed out changeset 08603e5ea8a0 (bug 1860492) Backed out changeset 93086bc64d37 (bug 1860492) Backed out changeset f8cbb9933469 (bug 1860492) Backed out changeset f5e2a92235f1 (bug 1860492) Backed out changeset 0038d6d54690 (bug 1860492) Backed out changeset 24a1fb93d4a8 (bug 1860492) Backed out changeset c2c11ee3f79f (bug 1860492) Backed out changeset 9983c1ddee85 (bug 1860492) Backed out changeset b9286e049dea (bug 1860492) Backed out changeset d1d98783c88d (bug 1860492) Backed out changeset 22dd17861e80 (bug 1860492) Backed out changeset 7d823668fba7 (bug 1860492) Backed out changeset 024863677345 (bug 1860492)
355 lines
13 KiB
HTML
355 lines
13 KiB
HTML
<!DOCTYPE HTML>
|
|
<title>Test ImageBitmap</title>
|
|
<meta charset="utf-8">
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
|
<body>
|
|
|
|
<img src="image_anim-gr.gif" id="image" class="resource">
|
|
<video width="320" height="240" src="http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.ogv&type=video/ogg&cors=anonymous" id="video" crossOrigin="anonymous" autoplay></video>
|
|
|
|
<canvas id="c1" class="output" width="128" height="128"></canvas>
|
|
<canvas id="c2" width="128" height="128"></canvas>
|
|
|
|
<script src="imagebitmap_bug1239300.js"></script>
|
|
<script src="imagebitmap_bug1239752.js"></script>
|
|
<script type="text/javascript">
|
|
|
|
SimpleTest.waitForExplicitFinish();
|
|
|
|
/**
|
|
* [isPixel description]
|
|
* @param {[type]} ctx : canvas context
|
|
* @param {[type]} x : pixel x coordinate
|
|
* @param {[type]} y : pixel y coordinate
|
|
* @param {[type]} c : a rgba color code
|
|
* @param {[type]} d : error duration
|
|
* @return {Promise}
|
|
*/
|
|
function isPixel(ctx, x, y, c, d) {
|
|
var pos = x + "," + y;
|
|
var color = c[0] + "," + c[1] + "," + c[2] + "," + c[3];
|
|
var pixel = ctx.getImageData(x, y, 1, 1);
|
|
var pr = pixel.data[0],
|
|
pg = pixel.data[1],
|
|
pb = pixel.data[2],
|
|
pa = pixel.data[3];
|
|
ok(c[0]-d <= pr && pr <= c[0]+d &&
|
|
c[1]-d <= pg && pg <= c[1]+d &&
|
|
c[2]-d <= pb && pb <= c[2]+d &&
|
|
c[3]-d <= pa && pa <= c[3]+d,
|
|
"pixel "+pos+" of "+ctx.canvas.id+" is "+pr+","+pg+","+pb+","+pa+"; expected "+color+" +/- "+d);
|
|
}
|
|
|
|
var TEST_BITMAPS = [
|
|
{'rect': [0, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [255, 0, 0, 255], 5]]},
|
|
{'rect': [128, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [0, 255, 0, 255], 5]]},
|
|
{'rect': [230, 230, 128, 128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5],
|
|
[100, 100, [0, 0, 0, 0], 5]]},
|
|
{'rect': [-64, -64, 512, 512], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 0, 0, 0], 5],
|
|
[100, 100, [255, 0, 0, 255], 5]]},
|
|
{'rect': [128, 128, -128, -128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5]]},
|
|
{'rect': [0, 0, 256, 256], 'draw': [0, 128, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 255, 0, 255], 5]]},
|
|
];
|
|
|
|
var canvas, ctx, ctx2, completedImage;
|
|
|
|
function failed(ex) {
|
|
ok(false, "Promise failure: " + ex);
|
|
}
|
|
|
|
function testDraw() {
|
|
var resolver, bitmaps = [], image = new Image();
|
|
|
|
image.src = 'image_rgrg-256x256.png';
|
|
var promise = new Promise(function (arg) { resolver = arg; });
|
|
|
|
function createBitmap(def) {
|
|
return createImageBitmap(image, def.rect[0], def.rect[1], def.rect[2], def.rect[3])
|
|
.then(function (bitmap) { def.bitmap = bitmap; }, failed);
|
|
};
|
|
|
|
image.onload = function() {
|
|
completedImage = image;
|
|
resolver(Promise.all(TEST_BITMAPS.map(createBitmap)));
|
|
};
|
|
|
|
function testPixel(test) {
|
|
isPixel(ctx, test[0], test[1], test[2], test[3]);
|
|
};
|
|
|
|
return promise.then(function() {
|
|
TEST_BITMAPS.forEach(function (test) {
|
|
if (!test.bitmap) { return; }
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
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]);
|
|
test.test.forEach(testPixel);
|
|
is(test.bitmap.width, Math.abs(test.rect[2]), "Bitmap has correct width " + test.bitmap.width);
|
|
is(test.bitmap.height, Math.abs(test.rect[3]), "Bitmap has correct height " + test.bitmap.height);
|
|
});
|
|
});
|
|
}
|
|
|
|
function testSources() {
|
|
ctx.fillStyle="#00FF00";
|
|
ctx.fillRect(0, 0, 128, 128);
|
|
|
|
function check(bitmap) {
|
|
ctx2.clearRect(0, 0, 128, 128);
|
|
ctx2.drawImage(bitmap, 0, 0);
|
|
isPixel(ctx2, 0, 0, [0, 255, 0, 255], 5);
|
|
};
|
|
|
|
function getPNGBlobBitmapPromise() {
|
|
return new Promise(function(resolve, reject) {
|
|
canvas.toBlob(function(blob) {
|
|
resolve(createImageBitmap(blob));
|
|
})
|
|
});
|
|
}
|
|
|
|
function getJPGBlobBitmapPromise() {
|
|
return new Promise(function(resolve, reject) {
|
|
canvas.toBlob(function(blob) {
|
|
resolve(createImageBitmap(blob));
|
|
}, "image/jpeg", 0.95)
|
|
});
|
|
}
|
|
|
|
return Promise.all([
|
|
createImageBitmap(document.getElementById('image')).then(check, failed), // HTMLImageElement
|
|
createImageBitmap(ctx).then(check, failed), // CanvasRenderingContext2D
|
|
createImageBitmap(canvas).then(check, failed), // HTMLCanvasElement
|
|
createImageBitmap(ctx).then(function (bitmap) { return createImageBitmap(bitmap).then(check, failed); }, failed), // ImageBitmap
|
|
createImageBitmap(document.getElementById('video'), 140, 0, 20, 20).then(check, failed), // HTMLVideoElement
|
|
createImageBitmap(ctx.getImageData(0, 0, 128, 128)).then(check, failed), // ImageData
|
|
getPNGBlobBitmapPromise().then(check, failed), // PNG blob
|
|
getJPGBlobBitmapPromise().then(check, failed), // JPEG blob
|
|
]);
|
|
}
|
|
|
|
function promiseThrows(p, name) {
|
|
var didThrow;
|
|
return p.then(function() { didThrow = false; },
|
|
function() { didThrow = true; })
|
|
.then(function() { ok(didThrow, name); });
|
|
}
|
|
|
|
function testExceptions() {
|
|
|
|
function createImageBitmapWithNeuturedImageData() {
|
|
return new Promise(function(resolve, reject) {
|
|
var tempImage = document.createElement('img');
|
|
tempImage.src = 'image_rgrg-256x256.png';
|
|
tempImage.onload = function() {
|
|
var tempCanvas = document.createElement('canvas');
|
|
var tempCtx = tempCanvas.getContext('2d');
|
|
tempCanvas.with = tempImage.naturalWidth;
|
|
tempCanvas.height = tempImage.naturalHeight;
|
|
tempCtx.drawImage(tempImage, 0, 0);
|
|
var tempWorker = new Worker("test_imagebitmap_on_worker.js");
|
|
var imageData = tempCtx.getImageData(0, 0, tempImage.naturalWidth, tempImage.naturalHeight);
|
|
tempWorker.postMessage(imageData.data.buffer, [imageData.data.buffer]);
|
|
tempWorker.terminate();
|
|
|
|
ok(!imageData.data.length, "Get a neutured ImageData.");
|
|
resolve(createImageBitmap(imageData));
|
|
}
|
|
});
|
|
}
|
|
|
|
function createImageBitmapWithCorruptedBlob() {
|
|
return new Promise(function(resolve, reject) {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open("GET", "image_error-early.png");
|
|
xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
|
|
xhr.onload = function()
|
|
{
|
|
ok(xhr.response, "Get a corrupted blob");
|
|
resolve(createImageBitmap(xhr.response));
|
|
}
|
|
xhr.send();
|
|
});
|
|
}
|
|
|
|
function createImageBitmapWithNonImageFile() {
|
|
return new Promise(function(resolve, reject) {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open("GET", "test_imagebitmap_on_worker.js");
|
|
xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
|
|
xhr.onload = function()
|
|
{
|
|
ok(xhr.response, "Get a non-image blob");
|
|
resolve(createImageBitmap(xhr.response));
|
|
}
|
|
xhr.send();
|
|
});
|
|
}
|
|
|
|
return Promise.all([
|
|
promiseThrows(createImageBitmap(new Image()), 'createImageBitmap should throw with unloaded image'),
|
|
promiseThrows(createImageBitmap(completedImage, 0, 0, 0, 0), 'createImageBitmap should throw with 0 width/height'),
|
|
promiseThrows(createImageBitmap(null), 'createImageBitmap should throw with null source'),
|
|
promiseThrows(createImageBitmapWithNeuturedImageData(), "createImageBitmap should throw with neutured ImageData"),
|
|
promiseThrows(createImageBitmapWithCorruptedBlob(), "createImageBitmap should throw with corrupted blob"),
|
|
promiseThrows(createImageBitmapWithNonImageFile(), "createImageBitmap should throw with non-image blob"),
|
|
]);
|
|
}
|
|
|
|
function testSecurityErrors() {
|
|
|
|
function getUncleanImagePromise() {
|
|
return new Promise(function(resolve, reject) {
|
|
var uncleanImage = document.createElement('img');
|
|
|
|
uncleanImage.onload = function() {
|
|
resolve(createImageBitmap(uncleanImage));
|
|
}
|
|
|
|
uncleanImage.onerror = function() {
|
|
reject();
|
|
}
|
|
|
|
uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
|
|
});
|
|
}
|
|
|
|
function getUncleanVideoPromise() {
|
|
return new Promise(function(resolve, reject) {
|
|
var uncleanVideo = document.createElement('video');
|
|
|
|
uncleanVideo.onloadeddata = function() {
|
|
resolve(createImageBitmap(uncleanVideo));
|
|
}
|
|
|
|
uncleanVideo.onerror = function() {
|
|
reject();
|
|
}
|
|
|
|
uncleanVideo.src = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.ogv&type=video/ogg";
|
|
uncleanVideo.play();
|
|
});
|
|
}
|
|
|
|
function getTaintedCanvasPromise() {
|
|
return new Promise(function(resolve, reject) {
|
|
var uncleanImage = document.createElement('img');
|
|
|
|
uncleanImage.onload = function() {
|
|
var taintedCanvas = document.createElement('canvas');
|
|
var taintedCtx = taintedCanvas.getContext('2d');
|
|
taintedCtx.drawImage(uncleanImage, 0, 0);
|
|
resolve(createImageBitmap(taintedCanvas));
|
|
}
|
|
|
|
uncleanImage.onerror = function() {
|
|
reject();
|
|
}
|
|
|
|
uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
|
|
});
|
|
}
|
|
|
|
function getTaintedCanvasRenderingContex2dPromise() {
|
|
return new Promise(function(resolve, reject) {
|
|
var uncleanImage = document.createElement('img');
|
|
|
|
uncleanImage.onload = function() {
|
|
var taintedCanvas = document.createElement('canvas');
|
|
var taintedCtx = taintedCanvas.getContext('2d');
|
|
taintedCtx.drawImage(uncleanImage, 0, 0);
|
|
resolve(createImageBitmap(taintedCtx));
|
|
}
|
|
|
|
uncleanImage.onerror = function() {
|
|
reject();
|
|
}
|
|
|
|
uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
|
|
});
|
|
}
|
|
|
|
function checkPromiseFailedWithSecurityError(p) {
|
|
return p.then(imageBitmap => {
|
|
ok(!!imageBitmap, "ImageBitmaps are always created");
|
|
const context = document.createElement("canvas").getContext("2d");
|
|
context.drawImage(imageBitmap, 0, 0);
|
|
try {
|
|
context.getImageData(0, 0, 1, 1);
|
|
ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully.");
|
|
} catch (ex) {
|
|
if (ex == "SecurityError: The operation is insecure.") {
|
|
ok(true, ex.message);
|
|
}
|
|
else {
|
|
ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex.message);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
return Promise.all([
|
|
checkPromiseFailedWithSecurityError(getUncleanImagePromise()),
|
|
checkPromiseFailedWithSecurityError(getUncleanVideoPromise()),
|
|
checkPromiseFailedWithSecurityError(getTaintedCanvasPromise()),
|
|
checkPromiseFailedWithSecurityError(getTaintedCanvasRenderingContex2dPromise()),
|
|
]);
|
|
}
|
|
|
|
function testCreatePattern() {
|
|
var resolve;
|
|
var promise = new Promise(function (arg) { resolve = arg; });
|
|
|
|
var TEST_PATTERN = [
|
|
[0, 0, [255, 0, 0, 255], 1],
|
|
[128, 128, [255, 0, 0, 255], 1],
|
|
[256, 256, [255, 0, 0, 255], 1],
|
|
[384, 0, [0, 255, 0, 255], 1],
|
|
[0, 384, [0, 255, 0, 255], 1],
|
|
];
|
|
|
|
var patternCanvas = document.createElement('canvas');
|
|
patternCanvas.width = "512";
|
|
patternCanvas.height = "512";
|
|
var patternCtx = patternCanvas.getContext('2d');
|
|
|
|
var image = new Image();
|
|
image.src = 'image_rgrg-256x256.png';
|
|
image.onload = function() {
|
|
var p = createImageBitmap(image);
|
|
p.then(function(bitmap) {
|
|
patternCtx.rect(0, 0, 512, 512);
|
|
patternCtx.fillStyle = patternCtx.createPattern(bitmap, "repeat");
|
|
patternCtx.fill();
|
|
document.body.appendChild(patternCanvas);
|
|
});
|
|
resolve(p);
|
|
}
|
|
|
|
return promise.then(function() {
|
|
TEST_PATTERN.forEach(function(test) {
|
|
isPixel(patternCtx, test[0], test[1], test[2], test[3]);
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
function runTests() {
|
|
canvas = document.getElementById('c1');
|
|
ctx = canvas.getContext('2d');
|
|
ctx2 = document.getElementById('c2').getContext('2d');
|
|
|
|
testDraw()
|
|
.then(testCreatePattern)
|
|
.then(testSources)
|
|
.then(testExceptions)
|
|
.then(testSecurityErrors)
|
|
.then(testBug1239300)
|
|
.then(testBug1239752)
|
|
.then(SimpleTest.finish, function(ev) { failed(ev); SimpleTest.finish(); });
|
|
}
|
|
|
|
addLoadEvent(runTests);
|
|
|
|
</script>
|
|
</body>
|