OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 */ | 25 */ |
26 | 26 |
27 #include "config.h" | 27 #include "config.h" |
28 #include "platform/graphics/BitmapImage.h" | 28 #include "platform/graphics/BitmapImage.h" |
29 | 29 |
| 30 #include "platform/PlatformInstrumentation.h" |
30 #include "platform/Timer.h" | 31 #include "platform/Timer.h" |
31 #include "platform/TraceEvent.h" | 32 #include "platform/TraceEvent.h" |
32 #include "platform/geometry/FloatRect.h" | 33 #include "platform/geometry/FloatRect.h" |
| 34 #include "platform/graphics/DeferredImageDecoder.h" |
33 #include "platform/graphics/GraphicsContextStateSaver.h" | 35 #include "platform/graphics/GraphicsContextStateSaver.h" |
34 #include "platform/graphics/ImageObserver.h" | 36 #include "platform/graphics/ImageObserver.h" |
35 #include "platform/graphics/skia/NativeImageSkia.h" | |
36 #include "platform/graphics/skia/SkiaUtils.h" | 37 #include "platform/graphics/skia/SkiaUtils.h" |
| 38 #include "third_party/skia/include/core/SkCanvas.h" |
37 #include "wtf/PassRefPtr.h" | 39 #include "wtf/PassRefPtr.h" |
38 #include "wtf/text/WTFString.h" | 40 #include "wtf/text/WTFString.h" |
39 | 41 |
40 namespace blink { | 42 namespace blink { |
41 | 43 |
42 PassRefPtr<BitmapImage> BitmapImage::create(PassRefPtr<NativeImageSkia> nativeIm
age, ImageObserver* observer) | 44 PassRefPtr<BitmapImage> BitmapImage::create(const SkBitmap& bitmap, ImageObserve
r* observer) |
43 { | 45 { |
44 if (!nativeImage) { | 46 if (bitmap.isNull()) { |
45 return BitmapImage::create(observer); | 47 return BitmapImage::create(observer); |
46 } | 48 } |
47 | 49 |
48 return adoptRef(new BitmapImage(nativeImage, observer)); | 50 return adoptRef(new BitmapImage(bitmap, observer)); |
49 } | 51 } |
50 | 52 |
51 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting(PassRefPtr<
NativeImageSkia> nativeImage, ImageOrientation orientation) | 53 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting(const SkBit
map& bitmap, ImageOrientation orientation) |
52 { | 54 { |
53 RefPtr<BitmapImage> result = create(nativeImage); | 55 RefPtr<BitmapImage> result = create(bitmap); |
54 result->m_frames[0].m_orientation = orientation; | 56 result->m_frames[0].m_orientation = orientation; |
55 if (orientation.usesWidthAsHeight()) | 57 if (orientation.usesWidthAsHeight()) |
56 result->m_sizeRespectingOrientation = IntSize(result->m_size.height(), r
esult->m_size.width()); | 58 result->m_sizeRespectingOrientation = IntSize(result->m_size.height(), r
esult->m_size.width()); |
57 return result.release(); | 59 return result.release(); |
58 } | 60 } |
59 | 61 |
60 BitmapImage::BitmapImage(ImageObserver* observer) | 62 BitmapImage::BitmapImage(ImageObserver* observer) |
61 : Image(observer) | 63 : Image(observer) |
62 , m_currentFrame(0) | 64 , m_currentFrame(0) |
63 , m_frames() | 65 , m_frames() |
64 , m_frameTimer(0) | 66 , m_frameTimer(0) |
65 , m_repetitionCount(cAnimationNone) | 67 , m_repetitionCount(cAnimationNone) |
66 , m_repetitionCountStatus(Unknown) | 68 , m_repetitionCountStatus(Unknown) |
67 , m_repetitionsComplete(0) | 69 , m_repetitionsComplete(0) |
68 , m_desiredFrameStartTime(0) | 70 , m_desiredFrameStartTime(0) |
69 , m_frameCount(0) | 71 , m_frameCount(0) |
70 , m_animationPolicy(ImageAnimationPolicyAllowed) | 72 , m_animationPolicy(ImageAnimationPolicyAllowed) |
71 , m_isSolidColor(false) | 73 , m_isSolidColor(false) |
72 , m_checkedForSolidColor(false) | 74 , m_checkedForSolidColor(false) |
73 , m_animationFinished(false) | 75 , m_animationFinished(false) |
74 , m_allDataReceived(false) | 76 , m_allDataReceived(false) |
75 , m_haveSize(false) | 77 , m_haveSize(false) |
76 , m_sizeAvailable(false) | 78 , m_sizeAvailable(false) |
77 , m_hasUniformFrameSize(true) | 79 , m_hasUniformFrameSize(true) |
78 , m_haveFrameCount(false) | 80 , m_haveFrameCount(false) |
79 { | 81 { |
80 } | 82 } |
81 | 83 |
82 BitmapImage::BitmapImage(PassRefPtr<NativeImageSkia> nativeImage, ImageObserver*
observer) | 84 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
83 : Image(observer) | 85 : Image(observer) |
84 , m_size(nativeImage->bitmap().width(), nativeImage->bitmap().height()) | 86 , m_size(bitmap.width(), bitmap.height()) |
85 , m_currentFrame(0) | 87 , m_currentFrame(0) |
86 , m_frames(0) | 88 , m_frames(0) |
87 , m_frameTimer(0) | 89 , m_frameTimer(0) |
88 , m_repetitionCount(cAnimationNone) | 90 , m_repetitionCount(cAnimationNone) |
89 , m_repetitionCountStatus(Unknown) | 91 , m_repetitionCountStatus(Unknown) |
90 , m_repetitionsComplete(0) | 92 , m_repetitionsComplete(0) |
91 , m_frameCount(1) | 93 , m_frameCount(1) |
92 , m_animationPolicy(ImageAnimationPolicyAllowed) | 94 , m_animationPolicy(ImageAnimationPolicyAllowed) |
93 , m_isSolidColor(false) | 95 , m_isSolidColor(false) |
94 , m_checkedForSolidColor(false) | 96 , m_checkedForSolidColor(false) |
95 , m_animationFinished(true) | 97 , m_animationFinished(true) |
96 , m_allDataReceived(true) | 98 , m_allDataReceived(true) |
97 , m_haveSize(true) | 99 , m_haveSize(true) |
98 , m_sizeAvailable(true) | 100 , m_sizeAvailable(true) |
99 , m_haveFrameCount(true) | 101 , m_haveFrameCount(true) |
100 { | 102 { |
101 // Since we don't have a decoder, we can't figure out the image orientation. | 103 // Since we don't have a decoder, we can't figure out the image orientation. |
102 // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. | 104 // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. |
103 m_sizeRespectingOrientation = m_size; | 105 m_sizeRespectingOrientation = m_size; |
104 | 106 |
105 m_frames.grow(1); | 107 m_frames.grow(1); |
106 m_frames[0].m_hasAlpha = !nativeImage->bitmap().isOpaque(); | 108 m_frames[0].m_hasAlpha = !bitmap.isOpaque(); |
107 m_frames[0].m_frame = nativeImage; | 109 m_frames[0].m_frame = bitmap; |
108 m_frames[0].m_haveMetadata = true; | 110 m_frames[0].m_haveMetadata = true; |
109 | 111 |
110 checkForSolidColor(); | 112 checkForSolidColor(); |
111 } | 113 } |
112 | 114 |
113 BitmapImage::~BitmapImage() | 115 BitmapImage::~BitmapImage() |
114 { | 116 { |
115 stopAnimation(); | 117 stopAnimation(); |
116 } | 118 } |
117 | 119 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 if (frameBytesCleared && imageObserver()) | 161 if (frameBytesCleared && imageObserver()) |
160 imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesClear
ed)); | 162 imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesClear
ed)); |
161 } | 163 } |
162 | 164 |
163 void BitmapImage::cacheFrame(size_t index) | 165 void BitmapImage::cacheFrame(size_t index) |
164 { | 166 { |
165 size_t numFrames = frameCount(); | 167 size_t numFrames = frameCount(); |
166 if (m_frames.size() < numFrames) | 168 if (m_frames.size() < numFrames) |
167 m_frames.grow(numFrames); | 169 m_frames.grow(numFrames); |
168 | 170 |
169 m_frames[index].m_frame = m_source.createFrameAtIndex(index); | 171 bool created = m_source.createFrameAtIndex(index, &m_frames[index].m_frame); |
170 if (numFrames == 1 && m_frames[index].m_frame) | 172 if (numFrames == 1 && created) |
171 checkForSolidColor(); | 173 checkForSolidColor(); |
172 | 174 |
173 m_frames[index].m_orientation = m_source.orientationAtIndex(index); | 175 m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
174 m_frames[index].m_haveMetadata = true; | 176 m_frames[index].m_haveMetadata = true; |
175 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); | 177 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); |
176 if (repetitionCount(false) != cAnimationNone) | 178 if (repetitionCount(false) != cAnimationNone) |
177 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); | 179 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); |
178 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); | 180 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); |
179 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); | 181 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); |
180 | 182 |
181 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); | 183 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); |
182 if (frameSize != m_size) | 184 if (frameSize != m_size) |
183 m_hasUniformFrameSize = false; | 185 m_hasUniformFrameSize = false; |
184 | 186 |
185 if (m_frames[index].m_frame) { | 187 if (created) { |
186 int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes); | 188 int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes); |
187 // The fully-decoded frame will subsume the partially decoded data used | 189 // The fully-decoded frame will subsume the partially decoded data used |
188 // to determine image properties. | 190 // to determine image properties. |
189 if (imageObserver()) | 191 if (imageObserver()) |
190 imageObserver()->decodedSizeChanged(this, deltaBytes); | 192 imageObserver()->decodedSizeChanged(this, deltaBytes); |
191 } | 193 } |
192 } | 194 } |
193 | 195 |
194 void BitmapImage::updateSize() const | 196 void BitmapImage::updateSize() const |
195 { | 197 { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 return m_source.hasColorProfile(); | 267 return m_source.hasColorProfile(); |
266 } | 268 } |
267 | 269 |
268 String BitmapImage::filenameExtension() const | 270 String BitmapImage::filenameExtension() const |
269 { | 271 { |
270 return m_source.filenameExtension(); | 272 return m_source.filenameExtension(); |
271 } | 273 } |
272 | 274 |
273 void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const Fl
oatRect& srcRect, SkXfermode::Mode compositeOp, RespectImageOrientationEnum shou
ldRespectImageOrientation) | 275 void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const Fl
oatRect& srcRect, SkXfermode::Mode compositeOp, RespectImageOrientationEnum shou
ldRespectImageOrientation) |
274 { | 276 { |
275 RefPtr<NativeImageSkia> image = nativeImageForCurrentFrame(); | 277 TRACE_EVENT0("skia", "BitmapImage::draw"); |
276 if (!image) | 278 |
| 279 SkBitmap bitmap; |
| 280 if (!bitmapForCurrentFrame(&bitmap)) |
277 return; // It's too early and we don't have an image yet. | 281 return; // It's too early and we don't have an image yet. |
278 | 282 |
279 FloatRect normDstRect = adjustForNegativeSize(dstRect); | 283 FloatRect normDstRect = adjustForNegativeSize(dstRect); |
280 FloatRect normSrcRect = adjustForNegativeSize(srcRect); | 284 FloatRect normSrcRect = adjustForNegativeSize(srcRect); |
281 normSrcRect.intersect(FloatRect(0, 0, image->bitmap().width(), image->bitmap
().height())); | 285 normSrcRect.intersect(FloatRect(0, 0, bitmap.width(), bitmap.height())); |
282 | 286 |
283 if (normSrcRect.isEmpty() || normDstRect.isEmpty()) | 287 if (normSrcRect.isEmpty() || normDstRect.isEmpty()) |
284 return; // Nothing to draw. | 288 return; // Nothing to draw. |
285 | 289 |
286 ImageOrientation orientation = DefaultImageOrientation; | 290 ImageOrientation orientation = DefaultImageOrientation; |
287 if (shouldRespectImageOrientation == RespectImageOrientation) | 291 if (shouldRespectImageOrientation == RespectImageOrientation) |
288 orientation = frameOrientationAtIndex(m_currentFrame); | 292 orientation = frameOrientationAtIndex(m_currentFrame); |
289 | 293 |
290 GraphicsContextStateSaver saveContext(*ctxt, false); | 294 GraphicsContextStateSaver saveContext(*ctxt, false); |
291 if (orientation != DefaultImageOrientation) { | 295 if (orientation != DefaultImageOrientation) { |
292 saveContext.save(); | 296 saveContext.save(); |
293 | 297 |
294 // ImageOrientation expects the origin to be at (0, 0) | 298 // ImageOrientation expects the origin to be at (0, 0) |
295 ctxt->translate(normDstRect.x(), normDstRect.y()); | 299 ctxt->translate(normDstRect.x(), normDstRect.y()); |
296 normDstRect.setLocation(FloatPoint()); | 300 normDstRect.setLocation(FloatPoint()); |
297 | 301 |
298 ctxt->concatCTM(orientation.transformFromDefault(normDstRect.size())); | 302 ctxt->concatCTM(orientation.transformFromDefault(normDstRect.size())); |
299 | 303 |
300 if (orientation.usesWidthAsHeight()) { | 304 if (orientation.usesWidthAsHeight()) { |
301 // The destination rect will have it's width and height already reve
rsed for the orientation of | 305 // The destination rect will have it's width and height already reve
rsed for the orientation of |
302 // the image, as it was needed for page layout, so we need to revers
e it back here. | 306 // the image, as it was needed for page layout, so we need to revers
e it back here. |
303 normDstRect = FloatRect(normDstRect.x(), normDstRect.y(), normDstRec
t.height(), normDstRect.width()); | 307 normDstRect = FloatRect(normDstRect.x(), normDstRect.y(), normDstRec
t.height(), normDstRect.width()); |
304 } | 308 } |
305 } | 309 } |
306 | 310 |
307 image->draw(ctxt, normSrcRect, normDstRect, compositeOp); | 311 bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap); |
| 312 bool isOpaque = bitmap.isOpaque(); |
| 313 |
| 314 { |
| 315 SkPaint paint; |
| 316 SkRect skSrcRect = normSrcRect; |
| 317 int initialSaveCount = ctxt->preparePaintForDrawRectToRect(&paint, skSrc
Rect, normDstRect, compositeOp, !isOpaque, isLazyDecoded, bitmap.isImmutable()); |
| 318 // We want to filter it if we decided to do interpolation above, or if |
| 319 // there is something interesting going on with the matrix (like a rotat
ion). |
| 320 // Note: for serialization, we will want to subset the bitmap first so w
e |
| 321 // don't send extra pixels. |
| 322 ctxt->drawBitmapRect(bitmap, &skSrcRect, normDstRect, &paint); |
| 323 ctxt->canvas()->restoreToCount(initialSaveCount); |
| 324 } |
| 325 |
| 326 if (isLazyDecoded) |
| 327 PlatformInstrumentation::didDrawLazyPixelRef(bitmap.getGenerationID()); |
308 | 328 |
309 if (ImageObserver* observer = imageObserver()) | 329 if (ImageObserver* observer = imageObserver()) |
310 observer->didDraw(this); | 330 observer->didDraw(this); |
311 | 331 |
312 startAnimation(); | 332 startAnimation(); |
313 } | 333 } |
314 | 334 |
315 size_t BitmapImage::frameCount() | 335 size_t BitmapImage::frameCount() |
316 { | 336 { |
317 if (!m_haveFrameCount) { | 337 if (!m_haveFrameCount) { |
(...skipping 14 matching lines...) Expand all Loading... |
332 m_sizeAvailable = m_source.isSizeAvailable(); | 352 m_sizeAvailable = m_source.isSizeAvailable(); |
333 | 353 |
334 return m_sizeAvailable; | 354 return m_sizeAvailable; |
335 } | 355 } |
336 | 356 |
337 bool BitmapImage::ensureFrameIsCached(size_t index) | 357 bool BitmapImage::ensureFrameIsCached(size_t index) |
338 { | 358 { |
339 if (index >= frameCount()) | 359 if (index >= frameCount()) |
340 return false; | 360 return false; |
341 | 361 |
342 if (index >= m_frames.size() || !m_frames[index].m_frame) | 362 if (index >= m_frames.size() || m_frames[index].m_frame.isNull()) |
343 cacheFrame(index); | 363 cacheFrame(index); |
344 | 364 |
345 return true; | 365 return true; |
346 } | 366 } |
347 | 367 |
348 PassRefPtr<NativeImageSkia> BitmapImage::frameAtIndex(size_t index) | 368 bool BitmapImage::frameAtIndex(size_t index, SkBitmap* bitmap) |
349 { | 369 { |
350 if (!ensureFrameIsCached(index)) | 370 if (!ensureFrameIsCached(index)) |
351 return nullptr; | 371 return false; |
352 | 372 |
353 return m_frames[index].m_frame; | 373 *bitmap = m_frames[index].m_frame; |
| 374 return true; |
354 } | 375 } |
355 | 376 |
356 bool BitmapImage::frameIsCompleteAtIndex(size_t index) | 377 bool BitmapImage::frameIsCompleteAtIndex(size_t index) |
357 { | 378 { |
358 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in
dex].m_isComplete) | 379 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in
dex].m_isComplete) |
359 return true; | 380 return true; |
360 | 381 |
361 return m_source.frameIsCompleteAtIndex(index); | 382 return m_source.frameIsCompleteAtIndex(index); |
362 } | 383 } |
363 | 384 |
364 float BitmapImage::frameDurationAtIndex(size_t index) | 385 float BitmapImage::frameDurationAtIndex(size_t index) |
365 { | 386 { |
366 if (index < m_frames.size() && m_frames[index].m_haveMetadata) | 387 if (index < m_frames.size() && m_frames[index].m_haveMetadata) |
367 return m_frames[index].m_duration; | 388 return m_frames[index].m_duration; |
368 | 389 |
369 return m_source.frameDurationAtIndex(index); | 390 return m_source.frameDurationAtIndex(index); |
370 } | 391 } |
371 | 392 |
372 PassRefPtr<NativeImageSkia> BitmapImage::nativeImageForCurrentFrame() | 393 bool BitmapImage::bitmapForCurrentFrame(SkBitmap* bitmap) |
373 { | 394 { |
374 return frameAtIndex(currentFrame()); | 395 return frameAtIndex(currentFrame(), bitmap); |
375 } | 396 } |
376 | 397 |
377 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() | 398 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() |
378 { | 399 { |
379 if (frameCount() > 1 && frameAtIndex(0)) | 400 SkBitmap bitmap; |
380 return BitmapImage::create(frameAtIndex(0)); | 401 if (frameCount() > 1 && frameAtIndex(0, &bitmap)) |
| 402 return BitmapImage::create(bitmap); |
381 | 403 |
382 return Image::imageForDefaultFrame(); | 404 return Image::imageForDefaultFrame(); |
383 } | 405 } |
384 | 406 |
385 bool BitmapImage::frameHasAlphaAtIndex(size_t index) | 407 bool BitmapImage::frameHasAlphaAtIndex(size_t index) |
386 { | 408 { |
387 if (m_frames.size() <= index) | 409 if (m_frames.size() <= index) |
388 return true; | 410 return true; |
389 | 411 |
390 if (m_frames[index].m_haveMetadata) | 412 if (m_frames[index].m_haveMetadata) |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 } | 639 } |
618 | 640 |
619 void BitmapImage::checkForSolidColor() | 641 void BitmapImage::checkForSolidColor() |
620 { | 642 { |
621 m_isSolidColor = false; | 643 m_isSolidColor = false; |
622 m_checkedForSolidColor = true; | 644 m_checkedForSolidColor = true; |
623 | 645 |
624 if (frameCount() > 1) | 646 if (frameCount() > 1) |
625 return; | 647 return; |
626 | 648 |
627 RefPtr<NativeImageSkia> frame = frameAtIndex(0); | 649 SkBitmap bitmap; |
628 | 650 if (frameAtIndex(0, &bitmap) && size().width() == 1 && size().height() == 1)
{ |
629 if (frame && size().width() == 1 && size().height() == 1) { | 651 SkAutoLockPixels lock(bitmap); |
630 SkAutoLockPixels lock(frame->bitmap()); | 652 if (!bitmap.getPixels()) |
631 if (!frame->bitmap().getPixels()) | |
632 return; | 653 return; |
633 | 654 |
634 m_isSolidColor = true; | 655 m_isSolidColor = true; |
635 m_solidColor = Color(frame->bitmap().getColor(0, 0)); | 656 m_solidColor = Color(bitmap.getColor(0, 0)); |
636 } | 657 } |
637 } | 658 } |
638 | 659 |
639 bool BitmapImage::mayFillWithSolidColor() | 660 bool BitmapImage::mayFillWithSolidColor() |
640 { | 661 { |
641 if (!m_checkedForSolidColor && frameCount() > 0) { | 662 if (!m_checkedForSolidColor && frameCount() > 0) { |
642 checkForSolidColor(); | 663 checkForSolidColor(); |
643 ASSERT(m_checkedForSolidColor); | 664 ASSERT(m_checkedForSolidColor); |
644 } | 665 } |
645 | 666 |
646 return m_isSolidColor && !m_currentFrame; | 667 return m_isSolidColor && !m_currentFrame; |
647 } | 668 } |
648 | 669 |
649 Color BitmapImage::solidColor() const | 670 Color BitmapImage::solidColor() const |
650 { | 671 { |
651 return m_solidColor; | 672 return m_solidColor; |
652 } | 673 } |
653 | 674 |
654 } // namespace blink | 675 } // namespace blink |
OLD | NEW |