Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013, Google Inc. All rights reserved. | 2 * Copyright (c) 2013, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "core/page/ImageBitmapFactories.h" | 32 #include "core/page/ImageBitmapFactories.h" |
| 33 | 33 |
| 34 #include "RuntimeEnabledFeatures.h" | 34 #include "RuntimeEnabledFeatures.h" |
| 35 #include "V8ImageBitmap.h" | 35 #include "V8ImageBitmap.h" |
| 36 #include "bindings/v8/ExceptionState.h" | 36 #include "bindings/v8/ExceptionState.h" |
| 37 #include "core/dom/ExceptionCode.h" | 37 #include "bindings/v8/ScriptScope.h" |
| 38 #include "bindings/v8/ScriptState.h" | |
| 38 #include "core/html/HTMLCanvasElement.h" | 39 #include "core/html/HTMLCanvasElement.h" |
| 39 #include "core/html/HTMLImageElement.h" | 40 #include "core/html/HTMLImageElement.h" |
| 40 #include "core/html/HTMLVideoElement.h" | 41 #include "core/html/HTMLVideoElement.h" |
| 41 #include "core/html/ImageData.h" | 42 #include "core/html/ImageData.h" |
| 42 #include "core/html/canvas/CanvasRenderingContext2D.h" | 43 #include "core/html/canvas/CanvasRenderingContext2D.h" |
| 43 #include "core/page/DOMWindow.h" | 44 #include "core/page/DOMWindow.h" |
| 44 #include "core/page/ImageBitmap.h" | 45 #include "core/page/ImageBitmap.h" |
| 46 #include "core/platform/SharedBuffer.h" | |
| 47 #include "core/platform/graphics/BitmapImage.h" | |
| 48 #include "core/platform/graphics/ImageSource.h" | |
| 49 #include "core/platform/graphics/skia/NativeImageSkia.h" | |
| 45 | 50 |
| 46 namespace WebCore { | 51 namespace WebCore { |
| 47 | 52 |
| 53 ImageBitmapLoader::ImageBitmapLoader(EventTarget* eventTarget, PassRefPtr<Script PromiseResolver> resolver, IntRect* cropRect) | |
| 54 : m_loader(FileReaderLoader::ReadAsArrayBuffer, this) | |
| 55 , m_eventTarget(eventTarget) | |
| 56 , m_scriptState(ScriptState::current()) | |
| 57 , m_resolver(resolver) | |
| 58 , m_cropRect(cropRect) | |
| 59 { | |
| 60 } | |
| 61 | |
| 62 void ImageBitmapLoader::start(Blob* blob) | |
| 63 { | |
| 64 m_loader.start(m_eventTarget->scriptExecutionContext(), *blob); | |
| 65 } | |
| 66 | |
| 67 void ImageBitmapLoader::didFinishLoading() | |
| 68 { | |
| 69 ScriptScope scope(m_scriptState); | |
| 70 RefPtr<ImageBitmap> imageBitmap; | |
| 71 if (!m_loader.arrayBufferResult()) { | |
| 72 m_resolver->reject(imageBitmap.release()); | |
| 73 return; | |
| 74 } | |
| 75 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create((char*)m_loader.arr ayBufferResult()->data(), m_loader.arrayBufferResult()->byteLength()); | |
| 76 | |
| 77 ImageSource* source = new ImageSource(); | |
| 78 source->setData(sharedBuffer.get(), true); | |
| 79 RefPtr<NativeImageSkia> imageSkia = source->createFrameAtIndex(0); | |
| 80 if (!imageSkia) { | |
| 81 m_resolver->reject(imageBitmap.release()); | |
| 82 return; | |
| 83 } | |
| 84 RefPtr<Image> image = BitmapImage::create(imageSkia); | |
| 85 | |
| 86 if (!m_cropRect) | |
| 87 m_cropRect = new IntRect(image->rect()); | |
| 88 if (!m_cropRect->width() || !m_cropRect->height()) { | |
| 89 m_resolver->reject(imageBitmap.release()); | |
| 90 return; | |
| 91 } | |
| 92 | |
| 93 imageBitmap = ImageBitmap::create(image.get(), *m_cropRect); | |
| 94 m_resolver->fulfill(imageBitmap.release()); | |
| 95 m_eventTarget->toDOMWindow()->finishedLoading(this); | |
| 96 } | |
| 97 | |
| 98 void ImageBitmapLoader::didFail(FileError::ErrorCode) | |
| 99 { | |
| 100 ScriptScope scope(m_scriptState); | |
| 101 RefPtr<ImageBitmap> imageBitmap; | |
| 102 m_resolver->reject(imageBitmap.release()); | |
| 103 } | |
| 104 | |
| 48 namespace ImageBitmapFactories { | 105 namespace ImageBitmapFactories { |
| 49 | 106 |
| 50 static LayoutSize sizeFor(HTMLImageElement* image) | 107 static LayoutSize sizeFor(HTMLImageElement* image) |
| 51 { | 108 { |
| 52 if (CachedImage* cachedImage = image->cachedImage()) | 109 if (CachedImage* cachedImage = image->cachedImage()) |
| 53 return cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FI XME: Not sure about this. | 110 return cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FI XME: Not sure about this. |
| 54 return IntSize(); | 111 return IntSize(); |
| 55 } | 112 } |
| 56 | 113 |
| 57 static IntSize sizeFor(HTMLVideoElement* video) | 114 static IntSize sizeFor(HTMLVideoElement* video) |
| 58 { | 115 { |
| 59 if (MediaPlayer* player = video->player()) | 116 if (MediaPlayer* player = video->player()) |
| 60 return player->naturalSize(); | 117 return player->naturalSize(); |
| 61 return IntSize(); | 118 return IntSize(); |
| 62 } | 119 } |
| 63 | 120 |
| 64 static ScriptObject resolveImageBitmap(PassRefPtr<ImageBitmap> imageBitmap) | 121 static ScriptObject fulfillImageBitmap(ScriptExecutionContext* context, PassRefP tr<ImageBitmap> imageBitmap) |
| 65 { | 122 { |
| 66 // Promises must be enabled. | 123 // Promises must be enabled. |
| 67 ASSERT(RuntimeEnabledFeatures::promiseEnabled()); | 124 ASSERT(RuntimeEnabledFeatures::promiseEnabled()); |
| 68 | 125 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(conte xt); |
| 69 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(); | |
| 70 resolver->fulfill(imageBitmap); | 126 resolver->fulfill(imageBitmap); |
| 71 return resolver->promise(); | 127 return resolver->promise(); |
| 72 } | 128 } |
| 73 | 129 |
| 74 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLImageElement* image , ExceptionState& es) | 130 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLImageElement* image , ExceptionState& es) |
| 75 { | 131 { |
| 76 LayoutSize s = sizeFor(image); | 132 LayoutSize s = sizeFor(image); |
| 77 return createImageBitmap(eventTarget, image, 0, 0, s.width(), s.height(), es ); | 133 return createImageBitmap(eventTarget, image, 0, 0, s.width(), s.height(), es ); |
| 78 } | 134 } |
| 79 | 135 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 98 if (!image->cachedImage()->image()->hasSingleSecurityOrigin()) { | 154 if (!image->cachedImage()->image()->hasSingleSecurityOrigin()) { |
| 99 es.throwDOMException(SecurityError); | 155 es.throwDOMException(SecurityError); |
| 100 return ScriptObject(); | 156 return ScriptObject(); |
| 101 } | 157 } |
| 102 if (!image->cachedImage()->passesAccessControlCheck(eventTarget->toDOMWindow ()->document()->securityOrigin()) | 158 if (!image->cachedImage()->passesAccessControlCheck(eventTarget->toDOMWindow ()->document()->securityOrigin()) |
| 103 && eventTarget->toDOMWindow()->document()->securityOrigin()->taintsCanvas(im age->src())) { | 159 && eventTarget->toDOMWindow()->document()->securityOrigin()->taintsCanvas(im age->src())) { |
| 104 es.throwDOMException(SecurityError); | 160 es.throwDOMException(SecurityError); |
| 105 return ScriptObject(); | 161 return ScriptObject(); |
| 106 } | 162 } |
| 107 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | 163 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 |
| 108 return resolveImageBitmap(ImageBitmap::create(image, IntRect(sx, sy, sw, sh) )); | 164 return fulfillImageBitmap(eventTarget->scriptExecutionContext(), ImageBitmap ::create(image, IntRect(sx, sy, sw, sh))); |
| 109 } | 165 } |
| 110 | 166 |
| 111 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video , ExceptionState& es) | 167 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video , ExceptionState& es) |
| 112 { | 168 { |
| 113 IntSize s = sizeFor(video); | 169 IntSize s = sizeFor(video); |
| 114 return createImageBitmap(eventTarget, video, 0, 0, s.width(), s.height(), es ); | 170 return createImageBitmap(eventTarget, video, 0, 0, s.width(), s.height(), es ); |
| 115 } | 171 } |
| 116 | 172 |
| 117 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video , int sx, int sy, int sw, int sh, ExceptionState& es) | 173 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video , int sx, int sy, int sw, int sh, ExceptionState& es) |
| 118 { | 174 { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 138 } | 194 } |
| 139 if (!video->hasSingleSecurityOrigin()) { | 195 if (!video->hasSingleSecurityOrigin()) { |
| 140 es.throwDOMException(SecurityError); | 196 es.throwDOMException(SecurityError); |
| 141 return ScriptObject(); | 197 return ScriptObject(); |
| 142 } | 198 } |
| 143 if (!video->player()->didPassCORSAccessCheck() && eventTarget->toDOMWindow() ->document()->securityOrigin()->taintsCanvas(video->currentSrc())) { | 199 if (!video->player()->didPassCORSAccessCheck() && eventTarget->toDOMWindow() ->document()->securityOrigin()->taintsCanvas(video->currentSrc())) { |
| 144 es.throwDOMException(SecurityError); | 200 es.throwDOMException(SecurityError); |
| 145 return ScriptObject(); | 201 return ScriptObject(); |
| 146 } | 202 } |
| 147 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | 203 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 |
| 148 return resolveImageBitmap(ImageBitmap::create(video, IntRect(sx, sy, sw, sh) )); | 204 return fulfillImageBitmap(eventTarget->scriptExecutionContext(), ImageBitmap ::create(video, IntRect(sx, sy, sw, sh))); |
| 149 } | 205 } |
| 150 | 206 |
| 151 ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2 D* context, ExceptionState& es) | 207 ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2 D* context, ExceptionState& es) |
| 152 { | 208 { |
| 153 return createImageBitmap(eventTarget, context->canvas(), es); | 209 return createImageBitmap(eventTarget, context->canvas(), es); |
| 154 } | 210 } |
| 155 | 211 |
| 156 ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2 D* context, int sx, int sy, int sw, int sh, ExceptionState& es) | 212 ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2 D* context, int sx, int sy, int sw, int sh, ExceptionState& es) |
| 157 { | 213 { |
| 158 return createImageBitmap(eventTarget, context->canvas(), sx, sy, sw, sh, es) ; | 214 return createImageBitmap(eventTarget, context->canvas(), sx, sy, sw, sh, es) ; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 171 } | 227 } |
| 172 if (!canvas->originClean()) { | 228 if (!canvas->originClean()) { |
| 173 es.throwDOMException(InvalidStateError); | 229 es.throwDOMException(InvalidStateError); |
| 174 return ScriptObject(); | 230 return ScriptObject(); |
| 175 } | 231 } |
| 176 if (!sw || !sh) { | 232 if (!sw || !sh) { |
| 177 es.throwDOMException(IndexSizeError); | 233 es.throwDOMException(IndexSizeError); |
| 178 return ScriptObject(); | 234 return ScriptObject(); |
| 179 } | 235 } |
| 180 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | 236 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 |
| 181 return resolveImageBitmap(ImageBitmap::create(canvas, IntRect(sx, sy, sw, sh ))); | 237 return fulfillImageBitmap(eventTarget->scriptExecutionContext(), ImageBitmap ::create(canvas, IntRect(sx, sy, sw, sh))); |
| 238 } | |
| 239 | |
| 240 ScriptObject createImageBitmap(EventTarget* eventTarget, Blob* blob, ExceptionSt ate& es) | |
| 241 { | |
| 242 // Promises must be enabled. | |
| 243 ASSERT(RuntimeEnabledFeatures::promiseEnabled()); | |
| 244 | |
| 245 if (!blob) { | |
| 246 es.throwDOMException(TypeError); | |
| 247 return ScriptObject(); | |
| 248 } | |
| 249 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(event Target->scriptExecutionContext()); | |
| 250 ImageBitmapLoader* loader = new ImageBitmapLoader(eventTarget, resolver, 0); | |
|
Justin Novosad
2013/08/07 19:35:12
AFAICT, we you are leaking the loader here.
| |
| 251 | |
| 252 // FIXME: the Promise should hold a reference to the ImageBitmapLoader, inst ead of the DOMWindow. | |
| 253 // This requires that a Promise object is returned from createImageBitmap me thods, instead of a ScriptObject. | |
| 254 eventTarget->toDOMWindow()->loadBlobAsync(loader, blob); | |
| 255 | |
| 256 return resolver->promise(); | |
| 257 } | |
| 258 | |
| 259 ScriptObject createImageBitmap(EventTarget* eventTarget, Blob* blob, int sx, int sy, int sw, int sh, ExceptionState& es) | |
| 260 { | |
| 261 // Promises must be enabled. | |
| 262 ASSERT(RuntimeEnabledFeatures::promiseEnabled()); | |
| 263 | |
| 264 if (!blob) { | |
| 265 es.throwDOMException(TypeError); | |
| 266 return ScriptObject(); | |
| 267 } | |
| 268 if (!sw || !sh) { | |
| 269 es.throwDOMException(IndexSizeError); | |
| 270 return ScriptObject(); | |
| 271 } | |
| 272 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(event Target->scriptExecutionContext()); | |
| 273 IntRect* cropRect = new IntRect(sx, sy, sw, sh); | |
| 274 ImageBitmapLoader* loader = new ImageBitmapLoader(eventTarget, resolver, cro pRect); | |
| 275 | |
| 276 // FIXME: the Promise should hold a reference to the ImageBitmapLoader, inst ead of the DOMWindow. | |
| 277 // This requires that a Promise object is returned from createImageBitmap me thods, instead of a ScriptObject. | |
| 278 eventTarget->toDOMWindow()->loadBlobAsync(loader, blob); | |
| 279 | |
| 280 return resolver->promise(); | |
| 182 } | 281 } |
| 183 | 282 |
| 184 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, Except ionState& es) | 283 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, Except ionState& es) |
| 185 { | 284 { |
| 186 return createImageBitmap(eventTarget, data, 0, 0, data->width(), data->heigh t(), es); | 285 return createImageBitmap(eventTarget, data, 0, 0, data->width(), data->heigh t(), es); |
| 187 } | 286 } |
| 188 | 287 |
| 189 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, int sx , int sy, int sw, int sh, ExceptionState& es) | 288 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, int sx , int sy, int sw, int sh, ExceptionState& es) |
| 190 { | 289 { |
| 191 if (!data) { | 290 if (!data) { |
| 192 es.throwTypeError(); | 291 es.throwTypeError(); |
| 193 return ScriptObject(); | 292 return ScriptObject(); |
| 194 } | 293 } |
| 195 if (!sw || !sh) { | 294 if (!sw || !sh) { |
| 196 es.throwDOMException(IndexSizeError); | 295 es.throwDOMException(IndexSizeError); |
| 197 return ScriptObject(); | 296 return ScriptObject(); |
| 198 } | 297 } |
| 199 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | 298 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 |
| 200 return resolveImageBitmap(ImageBitmap::create(data, IntRect(sx, sy, sw, sh)) ); | 299 return fulfillImageBitmap(eventTarget->scriptExecutionContext(), ImageBitmap ::create(data, IntRect(sx, sy, sw, sh))); |
| 201 } | 300 } |
| 202 | 301 |
| 203 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, Ex ceptionState& es) | 302 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, Ex ceptionState& es) |
| 204 { | 303 { |
| 205 return createImageBitmap(eventTarget, bitmap, 0, 0, bitmap->width(), bitmap- >height(), es); | 304 return createImageBitmap(eventTarget, bitmap, 0, 0, bitmap->width(), bitmap- >height(), es); |
| 206 } | 305 } |
| 207 | 306 |
| 208 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, in t sx, int sy, int sw, int sh, ExceptionState& es) | 307 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, in t sx, int sy, int sw, int sh, ExceptionState& es) |
| 209 { | 308 { |
| 210 if (!bitmap) { | 309 if (!bitmap) { |
| 211 es.throwTypeError(); | 310 es.throwTypeError(); |
| 212 return ScriptObject(); | 311 return ScriptObject(); |
| 213 } | 312 } |
| 214 if (!sw || !sh) { | 313 if (!sw || !sh) { |
| 215 es.throwDOMException(IndexSizeError); | 314 es.throwDOMException(IndexSizeError); |
| 216 return ScriptObject(); | 315 return ScriptObject(); |
| 217 } | 316 } |
| 218 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | 317 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 |
| 219 return resolveImageBitmap(ImageBitmap::create(bitmap, IntRect(sx, sy, sw, sh ))); | 318 return fulfillImageBitmap(eventTarget->scriptExecutionContext(), ImageBitmap ::create(bitmap, IntRect(sx, sy, sw, sh))); |
| 220 } | 319 } |
| 221 | 320 |
| 222 } // namespace ImageBitmapFactories | 321 } // namespace ImageBitmapFactories |
| 223 } // namespace WebCore | 322 } // namespace WebCore |
| OLD | NEW |