OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "core/frame/ImageBitmap.h" | 5 #include "core/frame/ImageBitmap.h" |
6 | 6 |
7 #include "core/html/HTMLCanvasElement.h" | 7 #include "core/html/HTMLCanvasElement.h" |
8 #include "core/html/HTMLVideoElement.h" | 8 #include "core/html/HTMLVideoElement.h" |
9 #include "core/html/ImageData.h" | 9 #include "core/html/ImageData.h" |
10 #include "platform/image-decoders/ImageDecoder.h" | 10 #include "platform/image-decoders/ImageDecoder.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 else | 159 else |
160 skiaImage = adoptRef(surface->newImageSnapshot()); | 160 skiaImage = adoptRef(surface->newImageSnapshot()); |
161 if (premultiplyAlpha) | 161 if (premultiplyAlpha) |
162 return StaticBitmapImage::create(skiaImage.release()); | 162 return StaticBitmapImage::create(skiaImage.release()); |
163 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); | 163 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); |
164 } | 164 } |
165 | 165 |
166 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum
ent* document, const ImageBitmapOptions& options) | 166 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum
ent* document, const ImageBitmapOptions& options) |
167 { | 167 { |
168 bool flipY; | 168 bool flipY; |
169 parseOptions(options, flipY); | 169 bool premultiplyAlpha; |
| 170 parseOptions(options, flipY, premultiplyAlpha); |
170 | 171 |
171 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, m_isP
remultiplied); | 172 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, premu
ltiplyAlpha); |
172 if (!m_image) | 173 if (!m_image) |
173 return; | 174 return; |
174 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin
())); | 175 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin
())); |
| 176 m_image->setPremultiplied(premultiplyAlpha); |
175 } | 177 } |
176 | 178 |
177 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Docum
ent* document, const ImageBitmapOptions& options) | 179 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Docum
ent* document, const ImageBitmapOptions& options) |
178 { | 180 { |
179 IntSize playerSize; | 181 IntSize playerSize; |
180 if (video->webMediaPlayer()) | 182 if (video->webMediaPlayer()) |
181 playerSize = video->webMediaPlayer()->naturalSize(); | 183 playerSize = video->webMediaPlayer()->naturalSize(); |
182 | 184 |
183 IntRect videoRect = IntRect(IntPoint(), playerSize); | 185 IntRect videoRect = IntRect(IntPoint(), playerSize); |
184 IntRect srcRect = intersection(cropRect, videoRect); | 186 IntRect srcRect = intersection(cropRect, videoRect); |
185 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque,
DoNotInitializeImagePixels); | 187 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque,
DoNotInitializeImagePixels); |
186 if (!buffer) | 188 if (!buffer) |
187 return; | 189 return; |
188 | 190 |
189 IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRe
ct.y())); | 191 IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRe
ct.y())); |
190 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size())
, nullptr); | 192 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size())
, nullptr); |
191 | 193 |
192 bool flipY; | 194 bool flipY; |
193 parseOptions(options, flipY); | 195 bool premultiplyAlpha; |
| 196 parseOptions(options, flipY, premultiplyAlpha); |
194 | 197 |
195 if (flipY || !m_isPremultiplied) { | 198 if (flipY || !premultiplyAlpha) { |
196 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAccelerat
ion, SnapshotReasonUnknown); | 199 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAccelerat
ion, SnapshotReasonUnknown); |
197 if (flipY) | 200 if (flipY) |
198 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha)
; | 201 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha)
; |
199 if (!m_isPremultiplied) | 202 if (!premultiplyAlpha) |
200 skiaImage = premulSkImageToUnPremul(skiaImage.get()); | 203 skiaImage = premulSkImageToUnPremul(skiaImage.get()); |
201 m_image = StaticBitmapImage::create(skiaImage.release()); | 204 m_image = StaticBitmapImage::create(skiaImage.release()); |
202 } else { | 205 } else { |
203 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 206 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
204 } | 207 } |
205 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin
())); | 208 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin
())); |
| 209 m_image->setPremultiplied(premultiplyAlpha); |
206 } | 210 } |
207 | 211 |
208 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect, con
st ImageBitmapOptions& options) | 212 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect, con
st ImageBitmapOptions& options) |
209 { | 213 { |
210 ASSERT(canvas->isPaintable()); | 214 ASSERT(canvas->isPaintable()); |
211 bool flipY; | 215 bool flipY; |
212 parseOptions(options, flipY); | 216 bool premultiplyAlpha; |
| 217 parseOptions(options, flipY, premultiplyAlpha); |
213 | 218 |
214 // canvas is always premultiplied, so set the last parameter to true and con
vert to un-premul later | 219 // canvas is always premultiplied, so set the last parameter to true and con
vert to un-premul later |
215 m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration).get(
), cropRect, flipY, true); | 220 m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration).get(
), cropRect, flipY, true); |
216 if (!m_image) | 221 if (!m_image) |
217 return; | 222 return; |
218 if (!m_isPremultiplied) | 223 if (!premultiplyAlpha) |
219 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima
geForCurrentFrame().get())); | 224 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima
geForCurrentFrame().get())); |
220 m_image->setOriginClean(canvas->originClean()); | 225 m_image->setOriginClean(canvas->originClean()); |
| 226 m_image->setPremultiplied(premultiplyAlpha); |
221 } | 227 } |
222 | 228 |
223 ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBi
tmapOptions& options) | 229 ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBi
tmapOptions& options) |
224 { | 230 { |
225 bool flipY; | 231 bool flipY; |
226 parseOptions(options, flipY); | 232 bool premultiplyAlpha; |
| 233 parseOptions(options, flipY, premultiplyAlpha); |
227 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size())); | 234 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size())); |
228 | 235 |
229 // treat non-premultiplyAlpha as a special case | 236 // treat non-premultiplyAlpha as a special case |
230 if (!m_isPremultiplied) { | 237 if (!premultiplyAlpha) { |
231 unsigned char* srcAddr = data->data()->data(); | 238 unsigned char* srcAddr = data->data()->data(); |
232 int srcHeight = data->size().height(); | 239 int srcHeight = data->size().height(); |
233 int dstHeight = cropRect.height(); | 240 int dstHeight = cropRect.height(); |
234 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k
RGBA color type. | 241 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k
RGBA color type. |
235 // For now, we swap R and B channel and uses kBGRA color type. | 242 // For now, we swap R and B channel and uses kBGRA color type. |
236 SkImageInfo info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_
8888_SkColorType, kUnpremul_SkAlphaType); | 243 SkImageInfo info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_
8888_SkColorType, kUnpremul_SkAlphaType); |
237 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); | 244 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); |
238 int dstPixelBytesPerRow = info.bytesPerPixel() * cropRect.width(); | 245 int dstPixelBytesPerRow = info.bytesPerPixel() * cropRect.width(); |
239 if (cropRect == IntRect(IntPoint(), data->size())) { | 246 if (cropRect == IntRect(IntPoint(), data->size())) { |
240 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY); | 247 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY); |
(...skipping 24 matching lines...) Expand all Loading... |
265 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j + 2]; | 272 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j + 2]; |
266 else if (j % 4 == 2) | 273 else if (j % 4 == 2) |
267 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j - 2]; | 274 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j - 2]; |
268 else | 275 else |
269 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; | 276 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; |
270 } | 277 } |
271 } | 278 } |
272 } | 279 } |
273 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, copie
dDataBuffer.release(), dstPixelBytesPerRow)); | 280 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, copie
dDataBuffer.release(), dstPixelBytesPerRow)); |
274 } | 281 } |
| 282 m_image->setPremultiplied(premultiplyAlpha); |
275 return; | 283 return; |
276 } | 284 } |
277 | 285 |
278 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque,
DoNotInitializeImagePixels); | 286 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque,
DoNotInitializeImagePixels); |
279 if (!buffer) | 287 if (!buffer) |
280 return; | 288 return; |
281 | 289 |
282 if (srcRect.isEmpty()) { | 290 if (srcRect.isEmpty()) { |
283 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 291 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
284 return; | 292 return; |
285 } | 293 } |
286 | 294 |
287 IntPoint dstPoint = IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRe
ct.y())); | 295 IntPoint dstPoint = IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRe
ct.y())); |
288 if (cropRect.x() < 0) | 296 if (cropRect.x() < 0) |
289 dstPoint.setX(-cropRect.x()); | 297 dstPoint.setX(-cropRect.x()); |
290 if (cropRect.y() < 0) | 298 if (cropRect.y() < 0) |
291 dstPoint.setY(-cropRect.y()); | 299 dstPoint.setY(-cropRect.y()); |
292 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); | 300 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); |
293 if (flipY) | 301 if (flipY) |
294 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI
mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph
a)); | 302 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI
mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph
a)); |
295 else | 303 else |
296 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 304 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
297 } | 305 } |
298 | 306 |
299 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const Ima
geBitmapOptions& options) | 307 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const Ima
geBitmapOptions& options) |
300 { | 308 { |
301 bool flipY; | 309 bool flipY; |
302 parseOptions(options, flipY); | 310 bool premultiplyAlpha; |
303 m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, m_isPremultiplie
d, bitmap->isPremultiplied() ? DontPremultiplyAlpha : PremultiplyAlpha); | 311 parseOptions(options, flipY, premultiplyAlpha); |
| 312 m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha
, bitmap->isPremultiplied() ? DontPremultiplyAlpha : PremultiplyAlpha); |
304 if (!m_image) | 313 if (!m_image) |
305 return; | 314 return; |
306 m_image->setOriginClean(bitmap->originClean()); | 315 m_image->setOriginClean(bitmap->originClean()); |
| 316 m_image->setPremultiplied(premultiplyAlpha); |
307 } | 317 } |
308 | 318 |
309 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cro
pRect, const ImageBitmapOptions& options) | 319 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cro
pRect, const ImageBitmapOptions& options) |
310 { | 320 { |
311 bool flipY; | 321 bool flipY; |
312 parseOptions(options, flipY); | 322 bool premultiplyAlpha; |
313 m_image = cropImage(image.get(), cropRect, flipY, m_isPremultiplied, Premult
iplyAlpha); | 323 parseOptions(options, flipY, premultiplyAlpha); |
| 324 m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, Premulti
plyAlpha); |
314 if (!m_image) | 325 if (!m_image) |
315 return; | 326 return; |
316 m_image->setOriginClean(image->originClean()); | 327 m_image->setOriginClean(image->originClean()); |
| 328 m_image->setPremultiplied(premultiplyAlpha); |
317 } | 329 } |
318 | 330 |
319 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) | 331 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) |
320 { | 332 { |
321 m_image = image; | 333 m_image = image; |
322 } | 334 } |
323 | 335 |
324 PassRefPtr<StaticBitmapImage> ImageBitmap::transfer() | 336 PassRefPtr<StaticBitmapImage> ImageBitmap::transfer() |
325 { | 337 { |
326 ASSERT(!isNeutered()); | 338 ASSERT(!isNeutered()); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 | 426 |
415 ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarg
et& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& optio
ns, ExceptionState& exceptionState) | 427 ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarg
et& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& optio
ns, ExceptionState& exceptionState) |
416 { | 428 { |
417 if (!sw || !sh) { | 429 if (!sw || !sh) { |
418 exceptionState.throwDOMException(IndexSizeError, String::format("The sou
rce %s provided is 0.", sw ? "height" : "width")); | 430 exceptionState.throwDOMException(IndexSizeError, String::format("The sou
rce %s provided is 0.", sw ? "height" : "width")); |
419 return ScriptPromise(); | 431 return ScriptPromise(); |
420 } | 432 } |
421 return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, IntRe
ct(sx, sy, sw, sh), options)); | 433 return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, IntRe
ct(sx, sy, sw, sh), options)); |
422 } | 434 } |
423 | 435 |
424 void ImageBitmap::parseOptions(const ImageBitmapOptions& options, bool& flipY) | 436 void ImageBitmap::parseOptions(const ImageBitmapOptions& options, bool& flipY, b
ool& premultiplyAlpha) |
425 { | 437 { |
426 if (options.imageOrientation() == imageOrientationFlipY) { | 438 if (options.imageOrientation() == imageOrientationFlipY) { |
427 flipY = true; | 439 flipY = true; |
428 } else { | 440 } else { |
429 flipY = false; | 441 flipY = false; |
430 ASSERT(options.imageOrientation() == imageBitmapOptionNone); | 442 ASSERT(options.imageOrientation() == imageBitmapOptionNone); |
431 } | 443 } |
432 if (options.premultiplyAlpha() == imageBitmapOptionNone) { | 444 if (options.premultiplyAlpha() == imageBitmapOptionNone) { |
433 m_isPremultiplied = false; | 445 premultiplyAlpha = false; |
434 } else { | 446 } else { |
| 447 premultiplyAlpha = true; |
435 ASSERT(options.premultiplyAlpha() == "default" || options.premultiplyAlp
ha() == "premultiply"); | 448 ASSERT(options.premultiplyAlpha() == "default" || options.premultiplyAlp
ha() == "premultiply"); |
436 } | 449 } |
437 } | 450 } |
438 | 451 |
439 PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status
, AccelerationHint, SnapshotReason, const FloatSize&) const | 452 PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status
, AccelerationHint, SnapshotReason, const FloatSize&) const |
440 { | 453 { |
441 *status = NormalSourceImageStatus; | 454 *status = NormalSourceImageStatus; |
442 return m_image ? m_image : nullptr; | 455 return m_image ? m_image : nullptr; |
443 } | 456 } |
444 | 457 |
445 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const | 458 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const |
446 { | 459 { |
447 } | 460 } |
448 | 461 |
449 FloatSize ImageBitmap::elementSize(const FloatSize&) const | 462 FloatSize ImageBitmap::elementSize(const FloatSize&) const |
450 { | 463 { |
451 return FloatSize(width(), height()); | 464 return FloatSize(width(), height()); |
452 } | 465 } |
453 | 466 |
454 DEFINE_TRACE(ImageBitmap) | 467 DEFINE_TRACE(ImageBitmap) |
455 { | 468 { |
456 } | 469 } |
457 | 470 |
458 } // namespace blink | 471 } // namespace blink |
OLD | NEW |