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

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

Issue 2553343003: ShapeDetection: add support for all CanvasImageSource input types (Closed)
Patch Set: reillyg@s comments Created 4 years 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
« no previous file with comments | « third_party/WebKit/Source/modules/shapedetection/ShapeDetector.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/ShapeDetector.h" 5 #include "modules/shapedetection/ShapeDetector.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"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 57 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
58 ScriptPromise promise = resolver->promise(); 58 ScriptPromise promise = resolver->promise();
59 59
60 CanvasImageSource* canvasImageSource; 60 CanvasImageSource* canvasImageSource;
61 if (imageSource.isHTMLImageElement()) { 61 if (imageSource.isHTMLImageElement()) {
62 canvasImageSource = imageSource.getAsHTMLImageElement(); 62 canvasImageSource = imageSource.getAsHTMLImageElement();
63 } else if (imageSource.isImageBitmap()) { 63 } else if (imageSource.isImageBitmap()) {
64 canvasImageSource = imageSource.getAsImageBitmap(); 64 canvasImageSource = imageSource.getAsImageBitmap();
65 } else if (imageSource.isHTMLVideoElement()) { 65 } else if (imageSource.isHTMLVideoElement()) {
66 canvasImageSource = imageSource.getAsHTMLVideoElement(); 66 canvasImageSource = imageSource.getAsHTMLVideoElement();
67 } else if (imageSource.isHTMLCanvasElement()) {
68 canvasImageSource = imageSource.getAsHTMLCanvasElement();
69 } else if (imageSource.isOffscreenCanvas()) {
70 canvasImageSource = imageSource.getAsOffscreenCanvas();
67 } else { 71 } else {
68 // TODO(mcasas): Implement more CanvasImageSources, https://crbug.com/659138 72 NOTREACHED() << "Unsupported CanvasImageSource";
69 NOTIMPLEMENTED() << "Unsupported CanvasImageSource";
70 resolver->reject( 73 resolver->reject(
71 DOMException::create(NotFoundError, "Unsupported source.")); 74 DOMException::create(NotSupportedError, "Unsupported source."));
72 return promise; 75 return promise;
73 } 76 }
74 77
75 if (canvasImageSource->wouldTaintOrigin( 78 if (canvasImageSource->wouldTaintOrigin(
76 scriptState->getExecutionContext()->getSecurityOrigin())) { 79 scriptState->getExecutionContext()->getSecurityOrigin())) {
77 resolver->reject( 80 resolver->reject(
78 DOMException::create(SecurityError, "Source would taint origin.")); 81 DOMException::create(SecurityError, "Source would taint origin."));
79 return promise; 82 return promise;
80 } 83 }
81 84
82 if (imageSource.isHTMLImageElement()) { 85 if (imageSource.isHTMLImageElement()) {
83 return detectShapesOnImageElement(resolver, 86 return detectShapesOnImageElement(resolver,
84 imageSource.getAsHTMLImageElement()); 87 imageSource.getAsHTMLImageElement());
85 } else if (imageSource.isImageBitmap()) {
86 return detectShapesOnImageBitmap(resolver, imageSource.getAsImageBitmap());
87 } else if (imageSource.isHTMLVideoElement()) {
88 return detectShapesOnVideoElement(resolver,
89 imageSource.getAsHTMLVideoElement());
90 } 88 }
91 89
92 NOTREACHED(); 90 // TODO(mcasas): Check if |video| is actually playing a MediaStream by using
93 return promise; 91 // HTMLMediaElement::isMediaStreamURL(video->currentSrc().getString()); if
92 // there is a local WebCam associated, there might be sophisticated ways to
93 // detect faces on it. Until then, treat as a normal <video> element.
94
95 const FloatSize size(canvasImageSource->sourceWidth(),
96 canvasImageSource->sourceHeight());
97
98 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus;
99 RefPtr<Image> image = canvasImageSource->getSourceImageForCanvas(
100 &sourceImageStatus, PreferNoAcceleration, SnapshotReasonDrawImage, size);
101 if (!image || sourceImageStatus != NormalSourceImageStatus) {
102 resolver->reject(
103 DOMException::create(InvalidStateError, "Invalid element or state."));
104 return promise;
105 }
106
107 SkPixmap pixmap;
108 RefPtr<Uint8Array> pixelData;
109 uint8_t* pixelDataPtr = nullptr;
110 WTF::CheckedNumeric<int> allocationSize = 0;
111
112 sk_sp<SkImage> skImage = image->imageForCurrentFrame();
113 // Use |skImage|'s pixels if it has direct access to them.
114 if (skImage->peekPixels(&pixmap)) {
115 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
116 allocationSize = pixmap.getSafeSize();
117 } else if (imageSource.isImageBitmap()) {
118 ImageBitmap* imageBitmap = imageSource.getAsImageBitmap();
119 pixelData = imageBitmap->copyBitmapData(imageBitmap->isPremultiplied()
120 ? PremultiplyAlpha
121 : DontPremultiplyAlpha,
122 N32ColorType);
123 pixelDataPtr = pixelData->data();
124 allocationSize = imageBitmap->size().area() * 4 /* bytes per pixel */;
125 } else {
126 // TODO(mcasas): retrieve the pixels from elsewhere.
127 NOTREACHED();
128 resolver->reject(DOMException::create(
129 InvalidStateError, "Failed to get pixels for current frame."));
130 return promise;
131 }
132
133 mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData(
134 resolver, pixelDataPtr, allocationSize.ValueOrDefault(0));
135 if (!sharedBufferHandle->is_valid())
136 return promise;
137
138 return doDetect(resolver, std::move(sharedBufferHandle), image->width(),
139 image->height());
94 } 140 }
95 141
96 ScriptPromise ShapeDetector::detectShapesOnImageElement( 142 ScriptPromise ShapeDetector::detectShapesOnImageElement(
97 ScriptPromiseResolver* resolver, 143 ScriptPromiseResolver* resolver,
98 const HTMLImageElement* img) { 144 const HTMLImageElement* img) {
99 ScriptPromise promise = resolver->promise(); 145 ScriptPromise promise = resolver->promise();
100 146
101 if (img->bitmapSourceSize().isZero()) { 147 if (img->bitmapSourceSize().isZero()) {
102 resolver->resolve(HeapVector<Member<DOMRect>>()); 148 resolver->resolve(HeapVector<Member<DOMRect>>());
103 return promise; 149 return promise;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 resolver->reject(DOMException::create( 199 resolver->reject(DOMException::create(
154 InvalidStateError, 200 InvalidStateError,
155 "Failed to read pixels: Unable to decompress or unsupported format.")); 201 "Failed to read pixels: Unable to decompress or unsupported format."));
156 return promise; 202 return promise;
157 } 203 }
158 204
159 return doDetect(resolver, std::move(sharedBufferHandle), img->naturalWidth(), 205 return doDetect(resolver, std::move(sharedBufferHandle), img->naturalWidth(),
160 img->naturalHeight()); 206 img->naturalHeight());
161 } 207 }
162 208
163 ScriptPromise ShapeDetector::detectShapesOnImageBitmap(
164 ScriptPromiseResolver* resolver,
165 ImageBitmap* imageBitmap) {
166 ScriptPromise promise = resolver->promise();
167
168 if (imageBitmap->isNeutered()) {
169 resolver->reject(
170 DOMException::create(InvalidStateError, "Neutered ImageBitmap."));
171 return promise;
172 }
173
174 if (imageBitmap->size().area() == 0) {
175 resolver->resolve(HeapVector<Member<DOMRect>>());
176 return promise;
177 }
178
179 SkPixmap pixmap;
180 RefPtr<Uint8Array> pixelData;
181 uint8_t* pixelDataPtr = nullptr;
182 WTF::CheckedNumeric<int> allocationSize = 0;
183 // Use |skImage|'s pixels if it has direct access to them, otherwise retrieve
184 // them from elsewhere via copyBitmapData().
185 sk_sp<SkImage> skImage = imageBitmap->bitmapImage()->imageForCurrentFrame();
186 if (skImage->peekPixels(&pixmap)) {
187 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
188 allocationSize = pixmap.getSafeSize();
189 } else {
190 pixelData = imageBitmap->copyBitmapData(imageBitmap->isPremultiplied()
191 ? PremultiplyAlpha
192 : DontPremultiplyAlpha,
193 N32ColorType);
194 pixelDataPtr = pixelData->data();
195 allocationSize = imageBitmap->size().area() * 4 /* bytes per pixel */;
196 }
197
198 mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData(
199 resolver, pixelDataPtr, allocationSize.ValueOrDefault(0));
200 if (!sharedBufferHandle->is_valid())
201 return promise;
202
203 return doDetect(resolver, std::move(sharedBufferHandle), imageBitmap->width(),
204 imageBitmap->height());
205 }
206
207 ScriptPromise ShapeDetector::detectShapesOnVideoElement(
208 ScriptPromiseResolver* resolver,
209 const HTMLVideoElement* video) {
210 ScriptPromise promise = resolver->promise();
211 // TODO(mcasas): Check if |video| is actually playing a MediaStream by using
212 // HTMLMediaElement::isMediaStreamURL(video->currentSrc().getString()); if
213 // there is a local WebCam associated, there might be sophisticated ways to
214 // detect faces on it. Until then, treat as a normal <video> element.
215
216 // !hasAvailableVideoFrame() is a bundle of invalid states.
217 if (!video->hasAvailableVideoFrame()) {
218 resolver->reject(DOMException::create(
219 InvalidStateError, "Invalid HTMLVideoElement or state."));
220 return promise;
221 }
222
223 const FloatSize videoSize(video->videoWidth(), video->videoHeight());
224 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus;
225 RefPtr<Image> image =
226 video->getSourceImageForCanvas(&sourceImageStatus, PreferNoAcceleration,
227 SnapshotReasonDrawImage, videoSize);
228
229 DCHECK_EQ(NormalSourceImageStatus, sourceImageStatus);
230
231 SkPixmap pixmap;
232 RefPtr<Uint8Array> pixelData;
233 uint8_t* pixelDataPtr = nullptr;
234 WTF::CheckedNumeric<int> allocationSize = 0;
235 // Use |skImage|'s pixels if it has direct access to them.
236 sk_sp<SkImage> skImage = image->imageForCurrentFrame();
237 if (skImage->peekPixels(&pixmap)) {
238 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
239 allocationSize = pixmap.getSafeSize();
240 } else {
241 // TODO(mcasas): retrieve the pixels from elsewhere.
242 NOTREACHED();
243 resolver->reject(DOMException::create(
244 InvalidStateError, "Failed to get pixels for current frame."));
245 return promise;
246 }
247
248 mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData(
249 resolver, pixelDataPtr, allocationSize.ValueOrDefault(0));
250 if (!sharedBufferHandle->is_valid())
251 return promise;
252
253 return doDetect(resolver, std::move(sharedBufferHandle), image->width(),
254 image->height());
255 }
256
257 } // namespace blink 209 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/shapedetection/ShapeDetector.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698