fune/dom/canvas/test/test_imagebitmap.html
Stanca Serban 3274be9ff2 Backed out 13 changesets (bug 1860492) for causing multiple failures.
Backed out changeset 1b6bef229ce4 (bug 1860492)
Backed out changeset 22a3235fe2dc (bug 1860492)
Backed out changeset a5b2e4d12e44 (bug 1860492)
Backed out changeset cbcb811ca382 (bug 1860492)
Backed out changeset d6a999866f19 (bug 1860492)
Backed out changeset 40cee82fa090 (bug 1860492)
Backed out changeset eeec1917ab49 (bug 1860492)
Backed out changeset cf1230802d5c (bug 1860492)
Backed out changeset b34aacf0e966 (bug 1860492)
Backed out changeset 45d137c795f1 (bug 1860492)
Backed out changeset fb667be5932d (bug 1860492)
Backed out changeset a6d22d73c8a5 (bug 1860492)
Backed out changeset c8b6c53698f5 (bug 1860492)
2024-03-22 18:18:12 +02:00

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>