1/* 2 * Copyright (c) 2013, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 29 */ 30 31#include "config.h" 32#include "core/page/ImageBitmapFactories.h" 33 34#include "RuntimeEnabledFeatures.h" 35#include "V8ImageBitmap.h" 36#include "bindings/v8/ExceptionState.h" 37#include "core/dom/ExceptionCode.h" 38#include "core/html/HTMLCanvasElement.h" 39#include "core/html/HTMLImageElement.h" 40#include "core/html/HTMLVideoElement.h" 41#include "core/html/ImageData.h" 42#include "core/html/canvas/CanvasRenderingContext2D.h" 43#include "core/page/DOMWindow.h" 44#include "core/page/ImageBitmap.h" 45 46namespace WebCore { 47 48namespace ImageBitmapFactories { 49 50static LayoutSize sizeFor(HTMLImageElement* image) 51{ 52 if (ImageResource* cachedImage = image->cachedImage()) 53 return cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this. 54 return IntSize(); 55} 56 57static IntSize sizeFor(HTMLVideoElement* video) 58{ 59 if (MediaPlayer* player = video->player()) 60 return player->naturalSize(); 61 return IntSize(); 62} 63 64static ScriptObject resolveImageBitmap(PassRefPtr<ImageBitmap> imageBitmap) 65{ 66 // Promises must be enabled. 67 ASSERT(RuntimeEnabledFeatures::promiseEnabled()); 68 69 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(); 70 resolver->fulfill(imageBitmap); 71 return resolver->promise(); 72} 73 74ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLImageElement* image, ExceptionState& es) 75{ 76 LayoutSize s = sizeFor(image); 77 return createImageBitmap(eventTarget, image, 0, 0, s.width(), s.height(), es); 78} 79 80ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLImageElement* image, int sx, int sy, int sw, int sh, ExceptionState& es) 81{ 82 if (!image) { 83 es.throwTypeError(); 84 return ScriptObject(); 85 } 86 if (!image->cachedImage()) { 87 es.throwDOMException(InvalidStateError); 88 return ScriptObject(); 89 } 90 if (image->cachedImage()->image()->isSVGImage()) { 91 es.throwDOMException(InvalidStateError); 92 return ScriptObject(); 93 } 94 if (!sw || !sh) { 95 es.throwDOMException(IndexSizeError); 96 return ScriptObject(); 97 } 98 if (!image->cachedImage()->image()->hasSingleSecurityOrigin()) { 99 es.throwDOMException(SecurityError); 100 return ScriptObject(); 101 } 102 if (!image->cachedImage()->passesAccessControlCheck(eventTarget->toDOMWindow()->document()->securityOrigin()) 103 && eventTarget->toDOMWindow()->document()->securityOrigin()->taintsCanvas(image->src())) { 104 es.throwDOMException(SecurityError); 105 return ScriptObject(); 106 } 107 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 108 return resolveImageBitmap(ImageBitmap::create(image, IntRect(sx, sy, sw, sh))); 109} 110 111ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video, ExceptionState& es) 112{ 113 IntSize s = sizeFor(video); 114 return createImageBitmap(eventTarget, video, 0, 0, s.width(), s.height(), es); 115} 116 117ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video, int sx, int sy, int sw, int sh, ExceptionState& es) 118{ 119 if (!video) { 120 es.throwTypeError(); 121 return ScriptObject(); 122 } 123 if (!video->player()) { 124 es.throwDOMException(InvalidStateError); 125 return ScriptObject(); 126 } 127 if (video->networkState() == HTMLMediaElement::NETWORK_EMPTY) { 128 es.throwDOMException(InvalidStateError); 129 return ScriptObject(); 130 } 131 if (video->player()->readyState() <= MediaPlayer::HaveMetadata) { 132 es.throwDOMException(InvalidStateError); 133 return ScriptObject(); 134 } 135 if (!sw || !sh) { 136 es.throwDOMException(IndexSizeError); 137 return ScriptObject(); 138 } 139 if (!video->hasSingleSecurityOrigin()) { 140 es.throwDOMException(SecurityError); 141 return ScriptObject(); 142 } 143 if (!video->player()->didPassCORSAccessCheck() && eventTarget->toDOMWindow()->document()->securityOrigin()->taintsCanvas(video->currentSrc())) { 144 es.throwDOMException(SecurityError); 145 return ScriptObject(); 146 } 147 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 148 return resolveImageBitmap(ImageBitmap::create(video, IntRect(sx, sy, sw, sh))); 149} 150 151ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2D* context, ExceptionState& es) 152{ 153 return createImageBitmap(eventTarget, context->canvas(), es); 154} 155 156ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2D* context, int sx, int sy, int sw, int sh, ExceptionState& es) 157{ 158 return createImageBitmap(eventTarget, context->canvas(), sx, sy, sw, sh, es); 159} 160 161ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLCanvasElement* canvas, ExceptionState& es) 162{ 163 return createImageBitmap(eventTarget, canvas, 0, 0, canvas->width(), canvas->height(), es); 164} 165 166ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLCanvasElement* canvas, int sx, int sy, int sw, int sh, ExceptionState& es) 167{ 168 if (!canvas) { 169 es.throwTypeError(); 170 return ScriptObject(); 171 } 172 if (!canvas->originClean()) { 173 es.throwDOMException(InvalidStateError); 174 return ScriptObject(); 175 } 176 if (!sw || !sh) { 177 es.throwDOMException(IndexSizeError); 178 return ScriptObject(); 179 } 180 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 181 return resolveImageBitmap(ImageBitmap::create(canvas, IntRect(sx, sy, sw, sh))); 182} 183 184ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, ExceptionState& es) 185{ 186 return createImageBitmap(eventTarget, data, 0, 0, data->width(), data->height(), es); 187} 188 189ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, int sx, int sy, int sw, int sh, ExceptionState& es) 190{ 191 if (!data) { 192 es.throwTypeError(); 193 return ScriptObject(); 194 } 195 if (!sw || !sh) { 196 es.throwDOMException(IndexSizeError); 197 return ScriptObject(); 198 } 199 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 200 return resolveImageBitmap(ImageBitmap::create(data, IntRect(sx, sy, sw, sh))); 201} 202 203ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, ExceptionState& es) 204{ 205 return createImageBitmap(eventTarget, bitmap, 0, 0, bitmap->width(), bitmap->height(), es); 206} 207 208ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, int sx, int sy, int sw, int sh, ExceptionState& es) 209{ 210 if (!bitmap) { 211 es.throwTypeError(); 212 return ScriptObject(); 213 } 214 if (!sw || !sh) { 215 es.throwDOMException(IndexSizeError); 216 return ScriptObject(); 217 } 218 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 219 return resolveImageBitmap(ImageBitmap::create(bitmap, IntRect(sx, sy, sw, sh))); 220} 221 222} // namespace ImageBitmapFactories 223} // namespace WebCore 224