Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/frame/ImageBitmap.h" | 10 #include "core/frame/ImageBitmap.h" |
| 11 #include "core/frame/LocalFrame.h" | 11 #include "core/frame/LocalFrame.h" |
| 12 #include "core/html/HTMLImageElement.h" | 12 #include "core/html/HTMLImageElement.h" |
| 13 #include "core/html/HTMLVideoElement.h" | 13 #include "core/html/HTMLVideoElement.h" |
| 14 #include "core/html/ImageData.h" | 14 #include "core/html/ImageData.h" |
| 15 #include "core/loader/resource/ImageResourceContent.h" | 15 #include "core/loader/resource/ImageResourceContent.h" |
| 16 #include "platform/graphics/Image.h" | 16 #include "platform/graphics/Image.h" |
| 17 #include "third_party/skia/include/core/SkImage.h" | 17 #include "third_party/skia/include/core/SkImage.h" |
| 18 #include "third_party/skia/include/core/SkImageInfo.h" | 18 #include "third_party/skia/include/core/SkImageInfo.h" |
| 19 #include "wtf/CheckedNumeric.h" | 19 #include "wtf/CheckedNumeric.h" |
| 20 | 20 |
| 21 namespace blink { | 21 namespace blink { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 mojo::ScopedSharedBufferHandle getSharedBufferOnData( | 25 skia::mojom::blink::BitmapPtr getBitmapOnData(int width, |
| 26 ScriptPromiseResolver* resolver, | 26 int height, |
|
mcasas
2017/01/24 00:52:06
get is usually reserved for getters/accessors and
| |
| 27 uint8_t* data, | 27 Vector<uint8_t> bitmapData) { |
| 28 int size) { | 28 skia::mojom::blink::BitmapPtr bitmap = skia::mojom::blink::Bitmap::New(); |
| 29 DCHECK(data); | |
| 30 DCHECK(size); | |
| 31 ScriptPromise promise = resolver->promise(); | |
| 32 | 29 |
| 33 mojo::ScopedSharedBufferHandle sharedBufferHandle = | 30 bitmap->color_type = (kN32_SkColorType == kRGBA_8888_SkColorType) |
| 34 mojo::SharedBufferHandle::Create(size); | 31 ? skia::mojom::ColorType::RGBA_8888 |
| 35 if (!sharedBufferHandle->is_valid()) { | 32 : skia::mojom::ColorType::BGRA_8888; |
| 36 resolver->reject( | 33 bitmap->width = width; |
| 37 DOMException::create(InvalidStateError, "Internal allocation error")); | 34 bitmap->height = height; |
| 38 return sharedBufferHandle; | 35 bitmap->pixel_data = std::move(bitmapData); |
| 39 } | |
| 40 | 36 |
| 41 const mojo::ScopedSharedBufferMapping mappedBuffer = | 37 return bitmap; |
| 42 sharedBufferHandle->Map(size); | |
| 43 DCHECK(mappedBuffer.get()); | |
| 44 memcpy(mappedBuffer.get(), data, size); | |
| 45 | |
| 46 return sharedBufferHandle; | |
| 47 } | 38 } |
| 48 | 39 |
| 49 } // anonymous namespace | 40 } // anonymous namespace |
| 50 | 41 |
| 51 ShapeDetector::ShapeDetector(LocalFrame& frame) { | 42 ShapeDetector::ShapeDetector(LocalFrame& frame) { |
| 52 DCHECK(frame.interfaceProvider()); | 43 DCHECK(frame.interfaceProvider()); |
| 53 } | 44 } |
| 54 | 45 |
| 55 ScriptPromise ShapeDetector::detect(ScriptState* scriptState, | 46 ScriptPromise ShapeDetector::detect(ScriptState* scriptState, |
| 56 const ImageBitmapSourceUnion& imageSource) { | 47 const ImageBitmapSourceUnion& imageSource) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 pixelDataPtr = pixelData->data(); | 124 pixelDataPtr = pixelData->data(); |
| 134 allocationSize = imageBitmap->size().area() * 4 /* bytes per pixel */; | 125 allocationSize = imageBitmap->size().area() * 4 /* bytes per pixel */; |
| 135 } else { | 126 } else { |
| 136 // TODO(mcasas): retrieve the pixels from elsewhere. | 127 // TODO(mcasas): retrieve the pixels from elsewhere. |
| 137 NOTREACHED(); | 128 NOTREACHED(); |
| 138 resolver->reject(DOMException::create( | 129 resolver->reject(DOMException::create( |
| 139 InvalidStateError, "Failed to get pixels for current frame.")); | 130 InvalidStateError, "Failed to get pixels for current frame.")); |
| 140 return promise; | 131 return promise; |
| 141 } | 132 } |
| 142 | 133 |
| 143 mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData( | 134 WTF::Vector<uint8_t> bitmapData; |
| 144 resolver, pixelDataPtr, allocationSize.ValueOrDefault(0)); | 135 bitmapData.append(pixelDataPtr, |
| 145 if (!sharedBufferHandle->is_valid()) | 136 static_cast<int>(allocationSize.ValueOrDefault(0))); |
| 146 return promise; | |
| 147 | 137 |
| 148 return doDetect(resolver, std::move(sharedBufferHandle), image->width(), | 138 return doDetect(resolver, getBitmapOnData(image->width(), image->height(), |
| 149 image->height()); | 139 std::move(bitmapData))); |
| 150 } | 140 } |
| 151 | 141 |
| 152 ScriptPromise ShapeDetector::detectShapesOnImageData( | 142 ScriptPromise ShapeDetector::detectShapesOnImageData( |
| 153 ScriptPromiseResolver* resolver, | 143 ScriptPromiseResolver* resolver, |
| 154 ImageData* imageData) { | 144 ImageData* imageData) { |
| 155 ScriptPromise promise = resolver->promise(); | 145 ScriptPromise promise = resolver->promise(); |
| 156 | 146 |
| 157 if (imageData->size().isZero()) { | 147 if (imageData->size().isZero()) { |
| 158 resolver->resolve(HeapVector<Member<DOMRect>>()); | 148 resolver->resolve(HeapVector<Member<DOMRect>>()); |
| 159 return promise; | 149 return promise; |
| 160 } | 150 } |
| 161 | 151 |
| 162 uint8_t* const data = imageData->data()->data(); | 152 uint8_t* const data = imageData->data()->data(); |
| 163 WTF::CheckedNumeric<int> allocationSize = imageData->size().area() * 4; | 153 WTF::CheckedNumeric<int> allocationSize = imageData->size().area() * 4; |
| 154 WTF::Vector<uint8_t> bitmapData; | |
| 155 bitmapData.append(data, static_cast<int>(allocationSize.ValueOrDefault(0))); | |
| 164 | 156 |
| 165 mojo::ScopedSharedBufferHandle sharedBufferHandle = | 157 return doDetect(resolver, |
| 166 getSharedBufferOnData(resolver, data, allocationSize.ValueOrDefault(0)); | 158 getBitmapOnData(imageData->width(), imageData->height(), |
| 167 if (!sharedBufferHandle->is_valid()) | 159 std::move(bitmapData))); |
| 168 return promise; | |
| 169 | |
| 170 return doDetect(resolver, std::move(sharedBufferHandle), imageData->width(), | |
| 171 imageData->height()); | |
| 172 } | 160 } |
| 173 | 161 |
| 174 ScriptPromise ShapeDetector::detectShapesOnImageElement( | 162 ScriptPromise ShapeDetector::detectShapesOnImageElement( |
| 175 ScriptPromiseResolver* resolver, | 163 ScriptPromiseResolver* resolver, |
| 176 const HTMLImageElement* img) { | 164 const HTMLImageElement* img) { |
| 177 ScriptPromise promise = resolver->promise(); | 165 ScriptPromise promise = resolver->promise(); |
| 178 | 166 |
| 179 if (img->bitmapSourceSize().isZero()) { | 167 if (img->bitmapSourceSize().isZero()) { |
| 180 resolver->resolve(HeapVector<Member<DOMRect>>()); | 168 resolver->resolve(HeapVector<Member<DOMRect>>()); |
| 181 return promise; | 169 return promise; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 202 DCHECK_EQ(img->naturalHeight(), static_cast<unsigned>(image->height())); | 190 DCHECK_EQ(img->naturalHeight(), static_cast<unsigned>(image->height())); |
| 203 | 191 |
| 204 if (!image) { | 192 if (!image) { |
| 205 resolver->reject(DOMException::create( | 193 resolver->reject(DOMException::create( |
| 206 InvalidStateError, "Failed to get image from current frame.")); | 194 InvalidStateError, "Failed to get image from current frame.")); |
| 207 return promise; | 195 return promise; |
| 208 } | 196 } |
| 209 | 197 |
| 210 const SkImageInfo skiaInfo = | 198 const SkImageInfo skiaInfo = |
| 211 SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType()); | 199 SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType()); |
| 200 size_t rowBytes = skiaInfo.minRowBytes(); | |
| 212 | 201 |
| 213 const uint32_t allocationSize = skiaInfo.getSafeSize(skiaInfo.minRowBytes()); | 202 Vector<uint8_t> bitmapData(skiaInfo.getSafeSize(rowBytes)); |
| 214 | 203 const SkPixmap pixmap(skiaInfo, bitmapData.data(), rowBytes); |
| 215 mojo::ScopedSharedBufferHandle sharedBufferHandle = | |
| 216 mojo::SharedBufferHandle::Create(allocationSize); | |
| 217 if (!sharedBufferHandle.is_valid()) { | |
| 218 DLOG(ERROR) << "Requested allocation : " << allocationSize | |
| 219 << "B, larger than |mojo::edk::kMaxSharedBufferSize| == 16MB "; | |
| 220 // TODO(xianglu): For now we reject the promise if the image is too large. | |
| 221 // But consider resizing the image to remove restriction on the user side. | |
| 222 // Also, add LayoutTests for this case later. | |
| 223 resolver->reject( | |
| 224 DOMException::create(InvalidStateError, "Image exceeds size limit.")); | |
| 225 return promise; | |
| 226 } | |
| 227 | |
| 228 const mojo::ScopedSharedBufferMapping mappedBuffer = | |
| 229 sharedBufferHandle->Map(allocationSize); | |
| 230 | |
| 231 const SkPixmap pixmap(skiaInfo, mappedBuffer.get(), skiaInfo.minRowBytes()); | |
| 232 if (!image->readPixels(pixmap, 0, 0)) { | 204 if (!image->readPixels(pixmap, 0, 0)) { |
| 233 resolver->reject(DOMException::create( | 205 resolver->reject(DOMException::create( |
| 234 InvalidStateError, | 206 InvalidStateError, |
| 235 "Failed to read pixels: Unable to decompress or unsupported format.")); | 207 "Failed to read pixels: Unable to decompress or unsupported format.")); |
| 236 return promise; | 208 return promise; |
| 237 } | 209 } |
| 238 | 210 |
| 239 return doDetect(resolver, std::move(sharedBufferHandle), img->naturalWidth(), | 211 return doDetect(resolver, |
| 240 img->naturalHeight()); | 212 getBitmapOnData(img->naturalWidth(), img->naturalHeight(), |
| 213 std::move(bitmapData))); | |
| 241 } | 214 } |
| 242 | 215 |
| 243 } // namespace blink | 216 } // namespace blink |
| OLD | NEW |