summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/test_imagebitmap_cropping.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/test_imagebitmap_cropping.html')
-rw-r--r--dom/canvas/test/test_imagebitmap_cropping.html274
1 files changed, 274 insertions, 0 deletions
diff --git a/dom/canvas/test/test_imagebitmap_cropping.html b/dom/canvas/test/test_imagebitmap_cropping.html
new file mode 100644
index 000000000..be7cd086f
--- /dev/null
+++ b/dom/canvas/test/test_imagebitmap_cropping.html
@@ -0,0 +1,274 @@
+<!DOCTYPE HTML>
+<title>Test ImageBitmap Cropping (Bug 1190210)</title>
+<meta charset="utf-8">
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<body>
+<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);
+}
+
+//
+// The pattern of the 320x240.ogv video.
+// .------------------------------------------------.
+// | 255 | 255 | 0 | 0 | 255 | 255 | 0 |
+// | 255 | 255 | 255 | 255 | 0 | 0 | 0 |
+// | 255 | 0 | 255 | 0 | 255 | 0 | 255 |
+// | | | | | | | |
+// ^ ^ ^ ^ ^ ^ ^ ^
+// 0 46 92 138 184 230 276 319
+//
+//
+// TEST_BITMAPS is a collection of test cases.
+// Each object in the TEST_BITMAPS array is a test case with the following
+// properties:
+// 1) croppingArea: indicating the cropping area in format (x, y, width, height).
+// 2) testedPixels: an array of pixels that is going to be checked.
+// Each item in the testedPixels array contains:
+// 2.1) "pixel": the coordinate of this pixel (x, y).
+// 2.2) "expectedColor": the expected color of this pixel (r, g, b, a).
+// 2.3) "tolerance": the acceptable tolerance of pixel values.
+//
+var TEST_BITMAPS = [
+ // Cropping area is exactly the same as source surface.
+ {'croppingArea': [0, 0, 320, 240],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [255, 255, 255, 255], "tolerance": 5},
+ {"pixel": [50, 0], "expectedColor": [255, 255, 0, 255], "tolerance": 5}]},
+ // Cropping area completely covers the source surface.
+ {'croppingArea': [-100, -100, 520, 440],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [519, 0], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [0, 439], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [519, 439], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [100, 100], "expectedColor": [255, 255, 255, 255], "tolerance": 5},
+ {"pixel": [150, 120], "expectedColor": [255, 255, 0, 255], "tolerance": 5},
+ {"pixel": [200, 140], "expectedColor": [0, 255, 255, 255], "tolerance": 5}]},
+ // Cropping area partially covers the left-upper part of the source surface.
+ {'croppingArea': [-100, -100, 320, 240],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0 ], "tolerance": 5},
+ {"pixel": [100, 100], "expectedColor": [255, 255, 255, 255], "tolerance": 5},
+ {"pixel": [150, 100], "expectedColor": [255, 255, 0, 255], "tolerance": 5}]},
+ // Cropping area partially covers the middle-upper part of the source surface.
+ {'croppingArea': [ 100, -100, 220, 240],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0 ], "tolerance": 5},
+ {"pixel": [0, 100], "expectedColor": [0, 255, 255, 255], "tolerance": 5},
+ {"pixel": [150, 100], "expectedColor": [255, 0, 0, 255], "tolerance": 5}]},
+ // Cropping area partially covers the right-upper part of the source surface.
+ {'croppingArea': [ 200, -100, 320, 240],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0 ], "tolerance": 5},
+ {"pixel": [0, 100], "expectedColor": [255, 0, 255, 255], "tolerance": 5},
+ {"pixel": [100, 100], "expectedColor": [0, 0, 255, 255], "tolerance": 5}]},
+ // Cropping area partially covers the left-center part of the source surface.
+ {'croppingArea': [-100, 100, 320, 120],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0 ], "tolerance": 5},
+ {"pixel": [200, 0], "expectedColor": [0, 255, 255, 255], "tolerance": 5},
+ {"pixel": [250, 10], "expectedColor": [0, 255, 0, 255], "tolerance": 5}]},
+ // Cropping area partially covers the left-bottom part of the source surface.
+ {'croppingArea': [-100, 200, 320, 240],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0 ], "tolerance": 5},
+ {"pixel": [100, 0], "expectedColor": [0, 60, 136, 255], "tolerance": 5},
+ {"pixel": [180, 10], "expectedColor": [255, 255, 255, 255], "tolerance": 5}]},
+ // Cropping area partially covers the middle-bottom part of the source surface.
+ {'croppingArea': [ 40, 200, 200, 100],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 60, 136, 255], "tolerance": 5},
+ {"pixel": [100, 20], "expectedColor": [107, 0, 210, 255], "tolerance": 5},
+ {"pixel": [80, 150], "expectedColor": [0, 0, 0, 0 ], "tolerance": 5}]},
+ // Cropping area partially covers the right-bottom part of the source surface.
+ {'croppingArea': [ 160, 100, 300, 300],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 255, 0, 255], "tolerance": 5},
+ {"pixel": [120, 20], "expectedColor": [0, 0, 255, 255], "tolerance": 5},
+ {"pixel": [299, 299], "expectedColor": [0, 0, 0, 0 ], "tolerance": 5}]},
+ // Cropping area is completely outside the source surface. (upper-left)
+ {'croppingArea': [-500, -500, 20, 20],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [19, 19], "expectedColor": [0, 0, 0, 0], "tolerance": 5}]},
+ // Cropping area is completely outside the source surface. (upper-right)
+ {'croppingArea': [ 500, -500, 20, 20],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [19, 19], "expectedColor": [0, 0, 0, 0], "tolerance": 5}]},
+ // Cropping area is completely outside the source surface. (bottom-left)
+ {'croppingArea': [-200, 500, 20, 20],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [19, 19], "expectedColor": [0, 0, 0, 0], "tolerance": 5}]},
+ // Cropping area is completely outside the source surface. (bottom-right)
+ {'croppingArea': [ 500, 200, 20, 20],
+ 'testedPixels': [{"pixel": [0, 0], "expectedColor": [0, 0, 0, 0], "tolerance": 5},
+ {"pixel": [19, 19], "expectedColor": [0, 0, 0, 0], "tolerance": 5}]},
+];
+
+function failed(ex) {
+ ok(false, "Promise failure: " + ex);
+}
+
+var gImage;
+var gVideo;
+var gCanvas;
+var gCtx;
+var gImageData;
+var gImageBitmap;
+var gPNGBlob;
+var gJPEGBlob;
+
+function prepareSources() {
+ gVideo = document.createElement("video");
+ gVideo.src = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/media/test/320x240.ogv&type=video/ogg&cors=anonymous";
+ gVideo.crossOrigin = "anonymous";
+ gVideo.autoplay = "true"
+
+
+ gCanvas = document.createElement("canvas");
+ gCtx = gCanvas.getContext("2d");
+
+ var resolver;
+ var promise = new Promise(function(resolve, reject) {
+ resolver = resolve;
+ });
+
+ // Prepare video.
+ gVideo.onloadeddata = function() {
+ ok(gVideo, "[Prepare Sources] gVideo is ok.");
+
+ // Prepare canvas.
+ gCanvas.width = gVideo.videoWidth;
+ gCanvas.height = gVideo.videoHeight;
+ gCtx.drawImage(gVideo, 0, 0);
+ ok(gCanvas, "[Prepare Sources] gCanvas is ok.");
+ ok(gCtx, "[Prepare Sources] gCtx is ok.");
+
+ // Prepare image.
+ gImage = document.createElement("img");
+ gImage.src = gCanvas.toDataURL();
+ var resolverImage;
+ var promiseImage = new Promise(function(resolve, reject) {
+ resolverImage = resolve;
+ });
+ gImage.onload = function() {
+ resolverImage(true);
+ }
+
+ // Prepare ImageData.
+ gImageData = gCtx.getImageData(0, 0, gCanvas.width, gCanvas.height);
+ ok(gImageData, "[Prepare Sources] gImageData is ok.");
+
+ // Prepapre PNG Blob.
+ var promisePNGBlob = new Promise(function(resolve, reject) {
+ gCanvas.toBlob(function(blob) {
+ gPNGBlob = blob;
+ ok(gPNGBlob, "[Prepare Sources] gPNGBlob is ok.");
+ resolve(true);
+ });
+ });
+
+ // Prepare JPEG Blob.
+ var promiseJPEGBlob = new Promise(function(resolve, reject) {
+ gCanvas.toBlob(function(blob) {
+ gJPEGBlob = blob;
+ ok(gJPEGBlob, "[Prepare Sources] gJPEGBlob is ok.");
+ resolve(true);
+ }, "image/jpeg", 0.95);
+ });
+
+ // Prepare ImageBitmap.
+ var promiseImageBitmap = new Promise(function(resolve, reject) {
+ var p = createImageBitmap(gVideo);
+ p.then(function(bitmap) {
+ gImageBitmap = bitmap;
+ ok(gImageBitmap, "[Prepare Sources] gImageBitmap is ok.");
+ resolve(true);
+ });
+ });
+
+ resolver(Promise.all([
+ promiseImage,
+ promisePNGBlob,
+ promiseJPEGBlob,
+ promiseImageBitmap
+ ]))
+ }
+
+ return promise;
+}
+
+function testCropping_randomTest(source) {
+ var canvasSrouce = document.createElement("canvas");
+ var ctxSource = canvasSrouce.getContext("2d");
+
+ var p = createImageBitmap(source);
+ p.then(function(bitmap) {
+ canvasSrouce.width = bitmap.width;
+ canvasSrouce.height = bitmap.height;
+ });
+}
+
+function testCropping(source) {
+ var canvas = document.createElement("canvas");
+ var ctx = canvas.getContext("2d");
+ document.body.appendChild(canvas);
+
+ function createBitmap(def) {
+ return createImageBitmap(source, def.croppingArea[0], def.croppingArea[1], def.croppingArea[2], def.croppingArea[3])
+ .then(function (bitmap) { def.bitmap = bitmap; }, failed);
+ };
+
+ var promise = new Promise(function(resolve, reject) {
+ resolve(Promise.all(TEST_BITMAPS.map(createBitmap)))
+ });
+
+ function testPixel(testedPixel) {
+ isPixel(ctx, testedPixel.pixel[0], testedPixel.pixel[1], testedPixel.expectedColor, testedPixel.tolerance);
+ };
+
+ return promise.then(function() {
+ TEST_BITMAPS.forEach(function (testCase) {
+ if (!testCase.bitmap) { return; }
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ canvas.width = testCase.bitmap.width;
+ canvas.height = testCase.bitmap.height;
+ ctx.drawImage(testCase.bitmap, 0, 0);
+ testCase.testedPixels.forEach(testPixel);
+ });
+ });
+}
+
+function runTests() {
+
+ prepareSources().
+ then( function() { return Promise.all([testCropping(gImage),
+ testCropping(gVideo),
+ testCropping(gCanvas),
+ testCropping(gCtx),
+ testCropping(gImageData),
+ testCropping(gImageBitmap),
+ testCropping(gPNGBlob),
+ testCropping(gJPEGBlob)]); }).
+ then(SimpleTest.finish, function(ev) { failed(ev); SimpleTest.finish(); });
+}
+
+addLoadEvent(runTests);
+
+</script>
+</body>