Chromium Code Reviews| Index: third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp |
| diff --git a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp |
| index 9f7100f852d2c4b2cae09b6e5dcec0929f0eeca3..42f954a481e8a3d66d27444f499d8a39653ca59d 100644 |
| --- a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp |
| +++ b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp |
| @@ -4,22 +4,128 @@ |
| #include "modules/shapedetection/FaceDetector.h" |
| -#include "bindings/core/v8/ScriptPromiseResolver.h" |
| #include "core/dom/DOMException.h" |
| +#include "core/dom/DOMRect.h" |
| +#include "core/dom/Document.h" |
| +#include "core/fetch/ImageResource.h" |
| +#include "core/frame/LocalFrame.h" |
| +#include "core/html/HTMLImageElement.h" |
| +#include "platform/graphics/Image.h" |
| +#include "public/platform/InterfaceProvider.h" |
| +#include "third_party/skia/include/core/SkImage.h" |
| +#include "third_party/skia/include/core/SkImageInfo.h" |
| namespace blink { |
| -FaceDetector* FaceDetector::create() |
| +namespace { |
| + |
| +mojo::ScopedSharedBufferHandle getSharedBufferHandle(const HTMLImageElement* img) |
| +{ |
| + ImageResource* imgResource = img->cachedImage(); |
|
mcasas
2016/09/30 02:14:59
ImageResource* const ?
xianglu
2016/09/30 16:37:41
Done.
|
| + if (!imgResource) { |
| + DLOG(ERROR) << "Failed to convert HTMLImageElement to ImageSource."; |
| + return mojo::ScopedSharedBufferHandle(); |
| + } |
| + |
| + Image* blinkImage = imgResource->getImage(); |
|
mcasas
2016/09/30 02:14:59
Image* const ?
xianglu
2016/09/30 16:37:41
Done.
|
| + if (!blinkImage) { |
| + DLOG(ERROR) << "Failed to convert ImageSource to blink::Image."; |
| + return mojo::ScopedSharedBufferHandle(); |
| + } |
| + |
| + sk_sp<SkImage> skImg = blinkImage->imageForCurrentFrame(); |
|
mcasas
2016/09/30 02:14:59
const sk_sp<SkImage> skiaImage ?
xianglu
2016/09/30 16:37:40
Done.
|
| + if (!skImg) { |
| + DLOG(ERROR) << "Failed to convert blink::Image to sk_sp<SkImage>."; |
| + return mojo::ScopedSharedBufferHandle(); |
| + } |
| + |
| + SkImageInfo dstInfo = SkImageInfo::MakeN32(skImg->width(), skImg->height(), skImg->alphaType()); |
|
mcasas
2016/09/30 02:14:59
const SkImageInfo skiaInfo ?
xianglu
2016/09/30 16:37:41
Done.
|
| + |
| + uint32_t allocationSize = dstInfo.getSafeSize(dstInfo.minRowBytes()); |
|
mcasas
2016/09/30 02:14:59
const
xianglu
2016/09/30 16:37:41
Done.
|
| + mojo::ScopedSharedBufferHandle sharedBufferHandle = mojo::SharedBufferHandle::Create(allocationSize); |
| + mojo::ScopedSharedBufferMapping mappingPtr = sharedBufferHandle->Map(allocationSize); |
| + DCHECK(mappingPtr); |
| + |
| + SkPixmap pixmap(dstInfo, mappingPtr.get(), dstInfo.minRowBytes()); |
|
mcasas
2016/09/30 02:14:59
const
xianglu
2016/09/30 16:37:41
Done.
|
| + if (!skImg->readPixels(pixmap, 0, 0)) { |
| + DLOG(ERROR) << "Failed to read pixels from sk_sp<SkImage>."; |
| + return mojo::ScopedSharedBufferHandle(); |
| + } |
| + |
| + DCHECK_EQ(img->naturalWidth(), skImg->width()); |
| + DCHECK_EQ(img->naturalHeight(), skImg->height()); |
|
mcasas
2016/09/30 02:14:59
Move these two contracts/preconditions to l.37,
i.
xianglu
2016/09/30 16:37:40
Done.
|
| + return sharedBufferHandle; |
| +} |
| + |
| +} // anonymous namespace |
| + |
| +FaceDetector* FaceDetector::create(const Document& document) |
| +{ |
| + return new FaceDetector(*document.frame()); |
| +} |
| + |
| +FaceDetector::FaceDetector(LocalFrame& frame) |
| { |
| - return new FaceDetector(); |
| + DCHECK(!m_service.is_bound()); |
| + DCHECK(frame.interfaceProvider()); |
| + frame.interfaceProvider()->getInterface(mojo::GetProxy(&m_service)); |
| } |
| -ScriptPromise FaceDetector::detect(ScriptState* scriptState, const HTMLImageElement* image) |
| +ScriptPromise FaceDetector::detect(ScriptState* scriptState, const HTMLImageElement* img) |
| { |
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| ScriptPromise promise = resolver->promise(); |
| - resolver->reject(DOMException::create(NotSupportedError, "Not implemented")); |
| + |
| + if (!m_service) { |
| + resolver->reject(DOMException::create(NotFoundError, "Face detection service unavailable.")); |
| + return promise; |
| + } |
| + |
| + if (!img) { |
| + resolver->reject(DOMException::create(SyntaxError, "The provided HTMLImageElement is empty.")); |
| + return promise; |
| + } |
| + |
| + // TODO(xianglu): Add security check when the spec is ready. https://crbug.com/646083 |
| + mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferHandle(img); |
| + if (!sharedBufferHandle->is_valid()) { |
| + resolver->reject(DOMException::create(SyntaxError, "Failed to get sharedBufferHandle.")); |
| + return promise; |
| + } |
| + |
| + m_serviceRequests.add(resolver); |
| + DCHECK(m_service.is_bound()); |
| + m_service->DetectFace( |
| + std::move(sharedBufferHandle), |
| + img->naturalWidth(), img->naturalHeight(), |
|
mcasas
2016/09/30 02:14:59
Strange indenting: either all parameters are in th
xianglu
2016/09/30 16:37:41
Done.
|
| + convertToBaseCallback(WTF::bind(&FaceDetector::onDetectFace, wrapPersistent(this), wrapPersistent(resolver))) |
| + ); |
| + sharedBufferHandle.reset(); |
| return promise; |
| } |
| + |
| +void FaceDetector::onDetectFace(ScriptPromiseResolver* resolver, mojo::WTFArray<mojom::blink::BoundingBoxPtr> boundingBoxes) |
| +{ |
| + if (!m_serviceRequests.contains(resolver)) |
| + return; |
| + |
| + HeapVector<Member<DOMRect>> resultRects; |
| + for (size_t i = 0; i < boundingBoxes.size(); i++) { |
| + resultRects.append(DOMRect::create( |
| + boundingBoxes.at(i)->x, |
| + boundingBoxes.at(i)->y, |
| + boundingBoxes.at(i)->width, |
| + boundingBoxes.at(i)->height)); |
| + } |
|
mcasas
2016/09/30 02:14:59
Consider for-range loop and const auto&:
Hea
xianglu
2016/09/30 16:37:41
There is no begin() function in mojo::WTFArray.
|
| + |
| + resolver->resolve(resultRects); |
| + m_serviceRequests.remove(resolver); |
| +} |
| + |
| +DEFINE_TRACE(FaceDetector) |
| +{ |
| + visitor->trace(m_serviceRequests); |
| +} |
| + |
| } // namespace blink |