Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp

Issue 2441953002: Shape Detection: Add two layout tests for face detection (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/shapedetection/FaceDetector.h" 5 #include "modules/shapedetection/FaceDetector.h"
6 6
7 #include "core/dom/DOMException.h" 7 #include "core/dom/DOMException.h"
8 #include "core/dom/DOMRect.h" 8 #include "core/dom/DOMRect.h"
9 #include "core/dom/Document.h" 9 #include "core/dom/Document.h"
10 #include "core/fetch/ImageResource.h" 10 #include "core/fetch/ImageResource.h"
11 #include "core/frame/LocalDOMWindow.h" 11 #include "core/frame/LocalDOMWindow.h"
12 #include "core/frame/LocalFrame.h" 12 #include "core/frame/LocalFrame.h"
13 #include "core/html/HTMLImageElement.h" 13 #include "core/html/HTMLImageElement.h"
14 #include "platform/graphics/Image.h" 14 #include "platform/graphics/Image.h"
15 #include "public/platform/InterfaceProvider.h" 15 #include "public/platform/InterfaceProvider.h"
16 #include "third_party/skia/include/core/SkImage.h" 16 #include "third_party/skia/include/core/SkImage.h"
17 #include "third_party/skia/include/core/SkImageInfo.h" 17 #include "third_party/skia/include/core/SkImageInfo.h"
18 18
19 namespace blink { 19 namespace blink {
20 20
21 namespace { 21 namespace {
22 22
23 mojo::ScopedSharedBufferHandle getSharedBufferHandle( 23 mojo::ScopedSharedBufferHandle getSharedBufferHandle(
24 const HTMLImageElement* img) { 24 const HTMLImageElement* img,
25 ScriptPromiseResolver* resolver) {
25 ImageResource* const imageResource = img->cachedImage(); 26 ImageResource* const imageResource = img->cachedImage();
26 if (!imageResource) { 27 if (!imageResource) {
27 DLOG(ERROR) << "Failed to convert HTMLImageElement to ImageSource."; 28 DLOG(ERROR) << "Failed to convert HTMLImageElement to ImageSource.";
29 resolver->reject(
30 DOMException::create(InvalidStateError, "HTMLImageElement is broken."));
mcasas 2016/10/21 04:41:46 I suggest you line up the comments in l.30, 38 and
xianglu 2016/10/21 21:08:30 Done.
28 return mojo::ScopedSharedBufferHandle(); 31 return mojo::ScopedSharedBufferHandle();
29 } 32 }
30 33
31 Image* const blinkImage = imageResource->getImage(); 34 Image* const blinkImage = imageResource->getImage();
32 if (!blinkImage) { 35 if (!blinkImage) {
33 DLOG(ERROR) << "Failed to convert ImageSource to blink::Image."; 36 DLOG(ERROR) << "Failed to convert ImageSource to blink::Image.";
mcasas 2016/10/21 04:41:46 s/ImageSource/ImageResource/
xianglu 2016/10/21 21:08:30 Done.
37 resolver->reject(
38 DOMException::create(InvalidStateError, "HTMLImageElement is broken."));
34 return mojo::ScopedSharedBufferHandle(); 39 return mojo::ScopedSharedBufferHandle();
35 } 40 }
36 41
37 const sk_sp<SkImage> image = blinkImage->imageForCurrentFrame(); 42 const sk_sp<SkImage> image = blinkImage->imageForCurrentFrame();
38 DCHECK_EQ(img->naturalWidth(), image->width()); 43 DCHECK_EQ(img->naturalWidth(), image->width());
39 DCHECK_EQ(img->naturalHeight(), image->height()); 44 DCHECK_EQ(img->naturalHeight(), image->height());
40 45
41 if (!image) { 46 if (!image) {
42 DLOG(ERROR) << "Failed to convert blink::Image to sk_sp<SkImage>."; 47 DLOG(ERROR) << "Failed to convert blink::Image to sk_sp<SkImage>.";
48 resolver->reject(
49 DOMException::create(InvalidStateError, "HTMLImageElement is broken."));
43 return mojo::ScopedSharedBufferHandle(); 50 return mojo::ScopedSharedBufferHandle();
44 } 51 }
45 52
46 const SkImageInfo skiaInfo = 53 const SkImageInfo skiaInfo =
47 SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType()); 54 SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType());
48 55
49 const uint32_t allocationSize = skiaInfo.getSafeSize(skiaInfo.minRowBytes()); 56 const uint32_t allocationSize = skiaInfo.getSafeSize(skiaInfo.minRowBytes());
50 57
51 mojo::ScopedSharedBufferHandle sharedBufferHandle = 58 mojo::ScopedSharedBufferHandle sharedBufferHandle =
52 mojo::SharedBufferHandle::Create(allocationSize); 59 mojo::SharedBufferHandle::Create(allocationSize);
53 if (!sharedBufferHandle.is_valid()) { 60 if (!sharedBufferHandle.is_valid()) {
54 // TODO(xianglu): Do something when the image is too large.
55 DLOG(ERROR) << "Failed to create a sharedBufferHandle. allocationSize = " 61 DLOG(ERROR) << "Failed to create a sharedBufferHandle. allocationSize = "
56 << allocationSize << "bytes. limit = 16777216"; 62 << allocationSize << "bytes. limit = 16777216";
mcasas 2016/10/21 04:41:46 This number is [1], right? Consider pulling it her
xianglu 2016/10/21 21:08:30 Done.
mcasas 2016/10/21 23:43:16 Well, I meant using |kMaxSharedBufferSize|, but no
mcasas 2016/10/24 17:38:56 This has not been addressed.
63 // TODO(xianglu): For now we reject the promise if the image is too large.
64 // But consider resizing the image to remove restriction on the user side.
65 // Also, add layouttest for this case later.
66 resolver->reject(DOMException::create(InvalidStateError,
67 "HTMLImageElement is too large."));
57 return mojo::ScopedSharedBufferHandle(); 68 return mojo::ScopedSharedBufferHandle();
58 } 69 }
59 70
60 const mojo::ScopedSharedBufferMapping mappedBuffer = 71 const mojo::ScopedSharedBufferMapping mappedBuffer =
61 sharedBufferHandle->Map(allocationSize); 72 sharedBufferHandle->Map(allocationSize);
62 73
63 const SkPixmap pixmap(skiaInfo, mappedBuffer.get(), skiaInfo.minRowBytes()); 74 const SkPixmap pixmap(skiaInfo, mappedBuffer.get(), skiaInfo.minRowBytes());
64 if (!image->readPixels(pixmap, 0, 0)) { 75 if (!image->readPixels(pixmap, 0, 0)) {
65 DLOG(ERROR) << "Failed to read pixels from sk_sp<SkImage>."; 76 DLOG(ERROR) << "Failed to read pixels from sk_sp<SkImage>.";
77 resolver->reject(
78 DOMException::create(InvalidStateError, "HTMLImageElement is broken."));
66 return mojo::ScopedSharedBufferHandle(); 79 return mojo::ScopedSharedBufferHandle();
67 } 80 }
68 81
69 return sharedBufferHandle; 82 return sharedBufferHandle;
70 } 83 }
71 84
72 } // anonymous namespace 85 } // anonymous namespace
73 86
74 FaceDetector* FaceDetector::create(ScriptState* scriptState) { 87 FaceDetector* FaceDetector::create(ScriptState* scriptState) {
75 return new FaceDetector(*scriptState->domWindow()->frame()); 88 return new FaceDetector(*scriptState->domWindow()->frame());
76 } 89 }
77 90
78 FaceDetector::FaceDetector(LocalFrame& frame) { 91 FaceDetector::FaceDetector(LocalFrame& frame) {
79 DCHECK(!m_service.is_bound()); 92 DCHECK(!m_service.is_bound());
80 DCHECK(frame.interfaceProvider()); 93 DCHECK(frame.interfaceProvider());
81 frame.interfaceProvider()->getInterface(mojo::GetProxy(&m_service)); 94 frame.interfaceProvider()->getInterface(mojo::GetProxy(&m_service));
82 } 95 }
83 96
84 ScriptPromise FaceDetector::detect(ScriptState* scriptState, 97 ScriptPromise FaceDetector::detect(ScriptState* scriptState,
85 const HTMLImageElement* img) { 98 const HTMLImageElement* img) {
86 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 99 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
87 ScriptPromise promise = resolver->promise(); 100 ScriptPromise promise = resolver->promise();
88 101
89 if (!m_service) { 102 // TODO(xianglu): Add test cases for cross-origin-images.
103 if (img->wouldTaintOrigin(
104 scriptState->getExecutionContext()->getSecurityOrigin())) {
90 resolver->reject(DOMException::create( 105 resolver->reject(DOMException::create(
91 NotFoundError, "Face detection service unavailable.")); 106 SecurityError, "Image source from a different origin."));
92 return promise; 107 return promise;
93 } 108 }
94 109
95 if (!img) { 110 if (img->bitmapSourceSize().isZero()) {
96 resolver->reject(DOMException::create( 111 resolver->reject(
97 SyntaxError, "The provided HTMLImageElement is empty.")); 112 DOMException::create(InvalidStateError, "HTMLImageElement is empty."));
98 return promise; 113 return promise;
99 } 114 }
100 115
101 // TODO(xianglu): Add security check when the spec is ready.
102 // https://crbug.com/646083
103 mojo::ScopedSharedBufferHandle sharedBufferHandle = 116 mojo::ScopedSharedBufferHandle sharedBufferHandle =
104 getSharedBufferHandle(img); 117 getSharedBufferHandle(img, resolver);
105 if (!sharedBufferHandle->is_valid()) { 118 if (!sharedBufferHandle->is_valid())
119 return promise;
120
121 if (!m_service) {
106 resolver->reject(DOMException::create( 122 resolver->reject(DOMException::create(
107 SyntaxError, "Request for sharedBufferHandle failed.")); 123 NotSupportedError, "Face detection service unavailable."));
108 return promise; 124 return promise;
109 } 125 }
110 126
111 m_serviceRequests.add(resolver); 127 m_serviceRequests.add(resolver);
112 DCHECK(m_service.is_bound()); 128 DCHECK(m_service.is_bound());
113 m_service->DetectFace(std::move(sharedBufferHandle), img->naturalWidth(), 129 m_service->DetectFace(std::move(sharedBufferHandle), img->naturalWidth(),
114 img->naturalHeight(), 130 img->naturalHeight(),
115 convertToBaseCallback(WTF::bind( 131 convertToBaseCallback(WTF::bind(
116 &FaceDetector::onDetectFace, wrapPersistent(this), 132 &FaceDetector::onDetectFace, wrapPersistent(this),
117 wrapPersistent(resolver)))); 133 wrapPersistent(resolver))));
(...skipping 16 matching lines...) Expand all
134 150
135 resolver->resolve(detectedFaces); 151 resolver->resolve(detectedFaces);
136 m_serviceRequests.remove(resolver); 152 m_serviceRequests.remove(resolver);
137 } 153 }
138 154
139 DEFINE_TRACE(FaceDetector) { 155 DEFINE_TRACE(FaceDetector) {
140 visitor->trace(m_serviceRequests); 156 visitor->trace(m_serviceRequests);
141 } 157 }
142 158
143 } // namespace blink 159 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698