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 259193e66be82d84c0f5a969ca73da37f550ed4c..fd3119df79b10a8a9b905b41b75a60f89f37d612 100644 |
--- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp |
+++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp |
@@ -22,19 +22,28 @@ |
namespace { |
-skia::mojom::blink::BitmapPtr createBitmapFromData(int width, |
- int height, |
- Vector<uint8_t> bitmapData) { |
- skia::mojom::blink::BitmapPtr bitmap = skia::mojom::blink::Bitmap::New(); |
- |
- bitmap->color_type = (kN32_SkColorType == kRGBA_8888_SkColorType) |
- ? skia::mojom::ColorType::RGBA_8888 |
- : skia::mojom::ColorType::BGRA_8888; |
- bitmap->width = width; |
- bitmap->height = height; |
- bitmap->pixel_data = std::move(bitmapData); |
- |
- return bitmap; |
+mojo::ScopedSharedBufferHandle getSharedBufferOnData( |
+ ScriptPromiseResolver* resolver, |
+ uint8_t* data, |
+ int size) { |
+ DCHECK(data); |
+ DCHECK(size); |
+ ScriptPromise promise = resolver->promise(); |
+ |
+ mojo::ScopedSharedBufferHandle sharedBufferHandle = |
+ mojo::SharedBufferHandle::Create(size); |
+ if (!sharedBufferHandle->is_valid()) { |
+ resolver->reject( |
+ DOMException::create(InvalidStateError, "Internal allocation error")); |
+ return sharedBufferHandle; |
+ } |
+ |
+ const mojo::ScopedSharedBufferMapping mappedBuffer = |
+ sharedBufferHandle->Map(size); |
+ DCHECK(mappedBuffer.get()); |
+ memcpy(mappedBuffer.get(), data, size); |
+ |
+ return sharedBufferHandle; |
} |
} // anonymous namespace |
@@ -125,13 +134,13 @@ |
return promise; |
} |
- WTF::Vector<uint8_t> bitmapData; |
- bitmapData.append(pixelDataPtr, |
- static_cast<int>(allocationSize.ValueOrDefault(0))); |
- |
- return doDetect(resolver, |
- createBitmapFromData(image->width(), image->height(), |
- std::move(bitmapData))); |
+ 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::detectShapesOnImageData( |
@@ -146,12 +155,14 @@ |
uint8_t* const data = imageData->data()->data(); |
WTF::CheckedNumeric<int> allocationSize = imageData->size().area() * 4; |
- WTF::Vector<uint8_t> bitmapData; |
- bitmapData.append(data, static_cast<int>(allocationSize.ValueOrDefault(0))); |
- |
- return doDetect(resolver, |
- createBitmapFromData(imageData->width(), imageData->height(), |
- std::move(bitmapData))); |
+ |
+ mojo::ScopedSharedBufferHandle sharedBufferHandle = |
+ getSharedBufferOnData(resolver, data, allocationSize.ValueOrDefault(0)); |
+ if (!sharedBufferHandle->is_valid()) |
+ return promise; |
+ |
+ return doDetect(resolver, std::move(sharedBufferHandle), imageData->width(), |
+ imageData->height()); |
} |
ScriptPromise ShapeDetector::detectShapesOnImageElement( |
@@ -190,10 +201,26 @@ |
const SkImageInfo skiaInfo = |
SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType()); |
- size_t rowBytes = skiaInfo.minRowBytes(); |
- |
- Vector<uint8_t> bitmapData(skiaInfo.getSafeSize(rowBytes)); |
- const SkPixmap pixmap(skiaInfo, bitmapData.data(), rowBytes); |
+ |
+ const uint32_t allocationSize = skiaInfo.getSafeSize(skiaInfo.minRowBytes()); |
+ |
+ mojo::ScopedSharedBufferHandle sharedBufferHandle = |
+ mojo::SharedBufferHandle::Create(allocationSize); |
+ if (!sharedBufferHandle.is_valid()) { |
+ DLOG(ERROR) << "Requested allocation : " << allocationSize |
+ << "B, larger than |mojo::edk::kMaxSharedBufferSize| == 16MB "; |
+ // TODO(xianglu): For now we reject the promise if the image is too large. |
+ // But consider resizing the image to remove restriction on the user side. |
+ // Also, add LayoutTests for this case later. |
+ resolver->reject( |
+ DOMException::create(InvalidStateError, "Image exceeds size limit.")); |
+ return promise; |
+ } |
+ |
+ const mojo::ScopedSharedBufferMapping mappedBuffer = |
+ sharedBufferHandle->Map(allocationSize); |
+ |
+ const SkPixmap pixmap(skiaInfo, mappedBuffer.get(), skiaInfo.minRowBytes()); |
if (!image->readPixels(pixmap, 0, 0)) { |
resolver->reject(DOMException::create( |
InvalidStateError, |
@@ -201,9 +228,8 @@ |
return promise; |
} |
- return doDetect( |
- resolver, createBitmapFromData(img->naturalWidth(), img->naturalHeight(), |
- std::move(bitmapData))); |
+ return doDetect(resolver, std::move(sharedBufferHandle), img->naturalWidth(), |
+ img->naturalHeight()); |
} |
} // namespace blink |