Index: third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp |
diff --git a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp |
index 6a76c7c29cf372c4ebfc6f4f7705516963833933..4da8d7c02e90cd38f14dc4171cd7228afb774127 100644 |
--- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp |
+++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp |
@@ -64,11 +64,14 @@ ScriptPromise ShapeDetector::detect(ScriptState* scriptState, |
canvasImageSource = imageSource.getAsImageBitmap(); |
} else if (imageSource.isHTMLVideoElement()) { |
canvasImageSource = imageSource.getAsHTMLVideoElement(); |
+ } else if (imageSource.isHTMLCanvasElement()) { |
+ canvasImageSource = imageSource.getAsHTMLCanvasElement(); |
+ } else if (imageSource.isOffscreenCanvas()) { |
+ canvasImageSource = imageSource.getAsOffscreenCanvas(); |
} else { |
- // TODO(mcasas): Implement more CanvasImageSources, https://crbug.com/659138 |
- NOTIMPLEMENTED() << "Unsupported CanvasImageSource"; |
+ NOTREACHED() << "Unsupported CanvasImageSource"; |
resolver->reject( |
- DOMException::create(NotFoundError, "Unsupported source.")); |
+ DOMException::create(NotSupportedError, "Unsupported source.")); |
return promise; |
} |
@@ -82,15 +85,58 @@ ScriptPromise ShapeDetector::detect(ScriptState* scriptState, |
if (imageSource.isHTMLImageElement()) { |
return detectShapesOnImageElement(resolver, |
imageSource.getAsHTMLImageElement()); |
+ } |
+ |
+ // TODO(mcasas): Check if |video| is actually playing a MediaStream by using |
+ // HTMLMediaElement::isMediaStreamURL(video->currentSrc().getString()); if |
+ // there is a local WebCam associated, there might be sophisticated ways to |
+ // detect faces on it. Until then, treat as a normal <video> element. |
+ |
+ const FloatSize size(canvasImageSource->sourceWidth(), |
+ canvasImageSource->sourceHeight()); |
+ |
+ SourceImageStatus sourceImageStatus = InvalidSourceImageStatus; |
+ RefPtr<Image> image = canvasImageSource->getSourceImageForCanvas( |
+ &sourceImageStatus, PreferNoAcceleration, SnapshotReasonDrawImage, size); |
+ if (!image || sourceImageStatus != NormalSourceImageStatus) { |
+ resolver->reject( |
+ DOMException::create(InvalidStateError, "Invalid element or state.")); |
+ return promise; |
+ } |
+ |
+ SkPixmap pixmap; |
+ RefPtr<Uint8Array> pixelData; |
+ uint8_t* pixelDataPtr = nullptr; |
+ WTF::CheckedNumeric<int> allocationSize = 0; |
+ |
+ sk_sp<SkImage> skImage = image->imageForCurrentFrame(); |
+ // Use |skImage|'s pixels if it has direct access to them. |
+ if (skImage->peekPixels(&pixmap)) { |
+ pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); |
+ allocationSize = pixmap.getSafeSize(); |
} else if (imageSource.isImageBitmap()) { |
- return detectShapesOnImageBitmap(resolver, imageSource.getAsImageBitmap()); |
- } else if (imageSource.isHTMLVideoElement()) { |
- return detectShapesOnVideoElement(resolver, |
- imageSource.getAsHTMLVideoElement()); |
+ ImageBitmap* imageBitmap = imageSource.getAsImageBitmap(); |
+ pixelData = imageBitmap->copyBitmapData(imageBitmap->isPremultiplied() |
+ ? PremultiplyAlpha |
+ : DontPremultiplyAlpha, |
+ N32ColorType); |
+ pixelDataPtr = pixelData->data(); |
+ allocationSize = imageBitmap->size().area() * 4 /* bytes per pixel */; |
+ } else { |
+ // TODO(mcasas): retrieve the pixels from elsewhere. |
+ NOTREACHED(); |
+ resolver->reject(DOMException::create( |
+ InvalidStateError, "Failed to get pixels for current frame.")); |
+ return promise; |
} |
- NOTREACHED(); |
- return promise; |
+ mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData( |
+ resolver, pixelDataPtr, allocationSize.ValueOrDefault(0)); |
+ if (!sharedBufferHandle->is_valid()) |
+ return promise; |
+ |
+ return doDetect(resolver, std::move(sharedBufferHandle), image->width(), |
+ image->height()); |
} |
ScriptPromise ShapeDetector::detectShapesOnImageElement( |
@@ -160,98 +206,4 @@ ScriptPromise ShapeDetector::detectShapesOnImageElement( |
img->naturalHeight()); |
} |
-ScriptPromise ShapeDetector::detectShapesOnImageBitmap( |
- ScriptPromiseResolver* resolver, |
- ImageBitmap* imageBitmap) { |
- ScriptPromise promise = resolver->promise(); |
- |
- if (imageBitmap->isNeutered()) { |
- resolver->reject( |
- DOMException::create(InvalidStateError, "Neutered ImageBitmap.")); |
- return promise; |
- } |
- |
- if (imageBitmap->size().area() == 0) { |
- resolver->resolve(HeapVector<Member<DOMRect>>()); |
- return promise; |
- } |
- |
- SkPixmap pixmap; |
- RefPtr<Uint8Array> pixelData; |
- uint8_t* pixelDataPtr = nullptr; |
- WTF::CheckedNumeric<int> allocationSize = 0; |
- // Use |skImage|'s pixels if it has direct access to them, otherwise retrieve |
- // them from elsewhere via copyBitmapData(). |
- sk_sp<SkImage> skImage = imageBitmap->bitmapImage()->imageForCurrentFrame(); |
- if (skImage->peekPixels(&pixmap)) { |
- pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); |
- allocationSize = pixmap.getSafeSize(); |
- } else { |
- pixelData = imageBitmap->copyBitmapData(imageBitmap->isPremultiplied() |
- ? PremultiplyAlpha |
- : DontPremultiplyAlpha, |
- N32ColorType); |
- pixelDataPtr = pixelData->data(); |
- allocationSize = imageBitmap->size().area() * 4 /* bytes per pixel */; |
- } |
- |
- mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData( |
- resolver, pixelDataPtr, allocationSize.ValueOrDefault(0)); |
- if (!sharedBufferHandle->is_valid()) |
- return promise; |
- |
- return doDetect(resolver, std::move(sharedBufferHandle), imageBitmap->width(), |
- imageBitmap->height()); |
-} |
- |
-ScriptPromise ShapeDetector::detectShapesOnVideoElement( |
- ScriptPromiseResolver* resolver, |
- const HTMLVideoElement* video) { |
- ScriptPromise promise = resolver->promise(); |
- // TODO(mcasas): Check if |video| is actually playing a MediaStream by using |
- // HTMLMediaElement::isMediaStreamURL(video->currentSrc().getString()); if |
- // there is a local WebCam associated, there might be sophisticated ways to |
- // detect faces on it. Until then, treat as a normal <video> element. |
- |
- // !hasAvailableVideoFrame() is a bundle of invalid states. |
- if (!video->hasAvailableVideoFrame()) { |
- resolver->reject(DOMException::create( |
- InvalidStateError, "Invalid HTMLVideoElement or state.")); |
- return promise; |
- } |
- |
- const FloatSize videoSize(video->videoWidth(), video->videoHeight()); |
- SourceImageStatus sourceImageStatus = InvalidSourceImageStatus; |
- RefPtr<Image> image = |
- video->getSourceImageForCanvas(&sourceImageStatus, PreferNoAcceleration, |
- SnapshotReasonDrawImage, videoSize); |
- |
- DCHECK_EQ(NormalSourceImageStatus, sourceImageStatus); |
- |
- SkPixmap pixmap; |
- RefPtr<Uint8Array> pixelData; |
- uint8_t* pixelDataPtr = nullptr; |
- WTF::CheckedNumeric<int> allocationSize = 0; |
- // Use |skImage|'s pixels if it has direct access to them. |
- sk_sp<SkImage> skImage = image->imageForCurrentFrame(); |
- if (skImage->peekPixels(&pixmap)) { |
- pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); |
- allocationSize = pixmap.getSafeSize(); |
- } else { |
- // TODO(mcasas): retrieve the pixels from elsewhere. |
- NOTREACHED(); |
- resolver->reject(DOMException::create( |
- InvalidStateError, "Failed to get pixels for current frame.")); |
- return promise; |
- } |
- |
- mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData( |
- resolver, pixelDataPtr, allocationSize.ValueOrDefault(0)); |
- if (!sharedBufferHandle->is_valid()) |
- return promise; |
- |
- return doDetect(resolver, std::move(sharedBufferHandle), image->width(), |
- image->height()); |
-} |
- |
} // namespace blink |