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 |