Commit abcbc58f authored by mcasas's avatar mcasas Committed by Commit bot

Shape Detection: resolve with empty results if any input element's dimension is zero

This CL homogenises the behaviour of the ShapeDetector's
detect() in case of an input element with any zero dimension.
Assuming such input element pass the cross origin test and
its underlying pixel data can be retrieved, then if either width
or height is zero, detect() Promise is resolved with an empty
array.

LayoutTests are adapted/extended/cleaned up.

BUG=674306

Review-Url: https://codereview.chromium.org/2626743002
Cr-Commit-Position: refs/heads/master@{#442737}
parent 8a062852
......@@ -3,11 +3,12 @@
<script src=../../resources/testharnessreport.js></script>
<script>
// This test verifies FaceDetector.detect() with an empty HTMLImageElement.
var createTestForEmptyInput = function(detectorName) {
// This test verifies *Detector.detect() returns an empty list when fed with
// an empty HTMLImageElement.
var createTestForEmptyInput = function(createDetector) {
async_test(function(t) {
var image = new Image();
var detector = eval("new " + detectorName + "();");
var detector = createDetector();
var tryDetection = function() {
detector.detect(image)
.then(detectionResult => {
......@@ -25,9 +26,9 @@ var createTestForEmptyInput = function(detectorName) {
};
generate_tests(createTestForEmptyInput, [
[ "Face", "FaceDetector" ],
[ "Barcode", "BarcodeDetector" ],
[ "Text", "TextDetector" ]
[ "Face", () => { return new FaceDetector(); } ],
[ "Barcode", () => { return new BarcodeDetector(); } ],
[ "Text", () => { return new TextDetector(); } ]
]);
</script>
......@@ -5,43 +5,59 @@
// Returns a Promise that is resolve()d if detect() is rejected. Needs an input
// |element| (e.g. an HTMLImageElement or HTMLVideoElement) and a |url| to load.
function detectFaceOnElementAndExpectError(element, url) {
function detectOnElementAndExpectError(createDetector, element, url) {
return new Promise(function(resolve, reject) {
var tryFaceDetection = function() {
var faceDetector = new FaceDetector();
faceDetector.detect(element)
.then(faceDetectionResult => {
var tryDetection = function() {
var detector = createDetector();
detector.detect(element)
.then(detectionResult => {
reject("Promise should have been rejected.");
})
.catch(error => {
resolve(error);
});
};
element.onload = tryFaceDetection;
element.onerror = tryFaceDetection;
element.onload = tryDetection;
element.onerror = tryDetection;
element.src = url;
});
}
};
// This test verifies that FaceDetector will reject an undecodable image.
promise_test(function(t) {
// This test verifies that a Detector will reject an undecodable image.
var createTestForBadImage = function(createDetector) {
promise_test(function(t) {
var image = new Image();
return detectFaceOnElementAndExpectError(image,
return detectOnElementAndExpectError(createDetector, image,
"../../imported/wpt/images/broken.png")
.then(function(error) {
assert_equals(error.name, "InvalidStateError");
assert_regexp_match(error.message, /Unable to decompress*/);
});
}, "FaceDetector should reject undecodable images with an InvalidStateError.");
}, "Detector should reject undecodable images with an InvalidStateError.");
};
// This test verifies that FaceDetector will reject a broken video.
promise_test(function(t) {
generate_tests(createTestForBadImage, [
[ "Face", () => { return new FaceDetector(); } ],
[ "Barcode", () => { return new BarcodeDetector(); } ],
[ "Text", () => { return new TextDetector(); } ]
]);
// This test verifies that a Detector will reject a broken video.
var createTestForBadVideo = function(createDetector) {
promise_test(function(t) {
var video = document.createElement('video');
return detectFaceOnElementAndExpectError(video, "content/garbage.webm")
return detectOnElementAndExpectError(createDetector, video,
"content/garbage.webm")
.then(function(error) {
assert_equals(error.name, "InvalidStateError");
});
}, "FaceDetector should reject undecodable videos with an InvalidStateError.");
}, "Detector should reject undecodable videos with an InvalidStateError.");
};
generate_tests(createTestForBadVideo, [
[ "Face", () => { return new FaceDetector(); } ],
[ "Barcode", () => { return new BarcodeDetector(); } ],
[ "Text", () => { return new TextDetector(); } ]
]);
</script>
......@@ -107,6 +107,10 @@ ScriptPromise ShapeDetector::detect(ScriptState* scriptState,
DOMException::create(InvalidStateError, "Invalid element or state."));
return promise;
}
if (size.isEmpty()) {
resolver->resolve(HeapVector<Member<DOMRect>>());
return promise;
}
SkPixmap pixmap;
RefPtr<Uint8Array> pixelData;
......@@ -150,6 +154,11 @@ ScriptPromise ShapeDetector::detectShapesOnImageData(
ImageData* imageData) {
ScriptPromise promise = resolver->promise();
if (imageData->size().isZero()) {
resolver->resolve(HeapVector<Member<DOMRect>>());
return promise;
}
uint8_t* const data = imageData->data()->data();
WTF::CheckedNumeric<int> allocationSize = imageData->size().area() * 4;
......@@ -167,7 +176,6 @@ ScriptPromise ShapeDetector::detectShapesOnImageElement(
const HTMLImageElement* img) {
ScriptPromise promise = resolver->promise();
// TODO(mcasas): reconsider this resolve(), https://crbug.com/674306.
if (img->bitmapSourceSize().isZero()) {
resolver->resolve(HeapVector<Member<DOMRect>>());
return promise;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment