| 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 "platform/graphics/BitmapImage.h" | 27 #include "platform/graphics/BitmapImage.h" |
| 28 | 28 |
| 29 #include "platform/PlatformInstrumentation.h" | 29 #include "platform/PlatformInstrumentation.h" |
| 30 #include "platform/RuntimeEnabledFeatures.h" |
| 30 #include "platform/Timer.h" | 31 #include "platform/Timer.h" |
| 31 #include "platform/geometry/FloatRect.h" | 32 #include "platform/geometry/FloatRect.h" |
| 32 #include "platform/graphics/BitmapImageMetrics.h" | 33 #include "platform/graphics/BitmapImageMetrics.h" |
| 33 #include "platform/graphics/DeferredImageDecoder.h" | 34 #include "platform/graphics/DeferredImageDecoder.h" |
| 34 #include "platform/graphics/ImageObserver.h" | 35 #include "platform/graphics/ImageObserver.h" |
| 35 #include "platform/graphics/StaticBitmapImage.h" | 36 #include "platform/graphics/StaticBitmapImage.h" |
| 36 #include "platform/graphics/skia/SkiaUtils.h" | 37 #include "platform/graphics/skia/SkiaUtils.h" |
| 37 #include "platform/tracing/TraceEvent.h" | 38 #include "platform/tracing/TraceEvent.h" |
| 38 #include "third_party/skia/include/core/SkCanvas.h" | 39 #include "third_party/skia/include/core/SkCanvas.h" |
| 39 #include "wtf/PassRefPtr.h" | 40 #include "wtf/PassRefPtr.h" |
| 40 #include "wtf/PtrUtil.h" | 41 #include "wtf/PtrUtil.h" |
| 41 #include "wtf/text/WTFString.h" | 42 #include "wtf/text/WTFString.h" |
| 42 | 43 |
| 43 namespace blink { | 44 namespace blink { |
| 44 | 45 |
| 46 namespace { |
| 47 |
| 48 ColorBehavior defaultColorBehavior() { |
| 49 // TODO(ccameron): ColorBehavior should be specified by the caller requesting |
| 50 // SkImages. |
| 51 // https://crbug.com/667420 |
| 52 if (RuntimeEnabledFeatures::trueColorRenderingEnabled()) |
| 53 return ColorBehavior::tag(); |
| 54 return ColorBehavior::transformToGlobalTarget(); |
| 55 } |
| 56 |
| 57 } // namespace |
| 58 |
| 45 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting( | 59 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting( |
| 46 const SkBitmap& bitmap, | 60 const SkBitmap& bitmap, |
| 47 ImageOrientation orientation) { | 61 ImageOrientation orientation) { |
| 48 if (bitmap.isNull()) { | 62 if (bitmap.isNull()) { |
| 49 return BitmapImage::create(); | 63 return BitmapImage::create(); |
| 50 } | 64 } |
| 51 | 65 |
| 52 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap)); | 66 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap)); |
| 53 result->m_frames[0].m_orientation = orientation; | 67 result->m_frames[0].m_orientation = orientation; |
| 54 if (orientation.usesWidthAsHeight()) | 68 if (orientation.usesWidthAsHeight()) |
| 55 result->m_sizeRespectingOrientation = result->m_size.transposedSize(); | 69 result->m_sizeRespectingOrientation = result->m_size.transposedSize(); |
| 56 return result.release(); | 70 return result.release(); |
| 57 } | 71 } |
| 58 | 72 |
| 59 BitmapImage::BitmapImage(ImageObserver* observer) | 73 BitmapImage::BitmapImage(ImageObserver* observer) |
| 60 : Image(observer), | 74 : Image(observer), |
| 61 m_currentFrame(0), | 75 m_currentFrame(0), |
| 62 m_cachedFrameIndex(0), | 76 m_cachedFrameIndex(0), |
| 77 m_cachedFrameColorBehavior(defaultColorBehavior()), |
| 63 m_repetitionCount(cAnimationNone), | 78 m_repetitionCount(cAnimationNone), |
| 64 m_repetitionCountStatus(Unknown), | 79 m_repetitionCountStatus(Unknown), |
| 65 m_repetitionsComplete(0), | 80 m_repetitionsComplete(0), |
| 66 m_desiredFrameStartTime(0), | 81 m_desiredFrameStartTime(0), |
| 67 m_frameCount(0), | 82 m_frameCount(0), |
| 68 m_animationPolicy(ImageAnimationPolicyAllowed), | 83 m_animationPolicy(ImageAnimationPolicyAllowed), |
| 69 m_animationFinished(false), | 84 m_animationFinished(false), |
| 70 m_allDataReceived(false), | 85 m_allDataReceived(false), |
| 71 m_haveSize(false), | 86 m_haveSize(false), |
| 72 m_sizeAvailable(false), | 87 m_sizeAvailable(false), |
| 73 m_haveFrameCount(false) {} | 88 m_haveFrameCount(false) {} |
| 74 | 89 |
| 75 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) | 90 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
| 76 : Image(observer), | 91 : Image(observer), |
| 77 m_size(bitmap.width(), bitmap.height()), | 92 m_size(bitmap.width(), bitmap.height()), |
| 78 m_currentFrame(0), | 93 m_currentFrame(0), |
| 79 m_cachedFrame(SkImage::MakeFromBitmap(bitmap)), | 94 m_cachedFrame(SkImage::MakeFromBitmap(bitmap)), |
| 80 m_cachedFrameIndex(0), | 95 m_cachedFrameIndex(0), |
| 96 m_cachedFrameColorBehavior(defaultColorBehavior()), |
| 81 m_repetitionCount(cAnimationNone), | 97 m_repetitionCount(cAnimationNone), |
| 82 m_repetitionCountStatus(Unknown), | 98 m_repetitionCountStatus(Unknown), |
| 83 m_repetitionsComplete(0), | 99 m_repetitionsComplete(0), |
| 84 m_frameCount(1), | 100 m_frameCount(1), |
| 85 m_animationPolicy(ImageAnimationPolicyAllowed), | 101 m_animationPolicy(ImageAnimationPolicyAllowed), |
| 86 m_animationFinished(true), | 102 m_animationFinished(true), |
| 87 m_allDataReceived(true), | 103 m_allDataReceived(true), |
| 88 m_haveSize(true), | 104 m_haveSize(true), |
| 89 m_sizeAvailable(true), | 105 m_sizeAvailable(true), |
| 90 m_haveFrameCount(true) { | 106 m_haveFrameCount(true) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 } | 139 } |
| 124 | 140 |
| 125 size_t BitmapImage::totalFrameBytes() { | 141 size_t BitmapImage::totalFrameBytes() { |
| 126 const size_t numFrames = frameCount(); | 142 const size_t numFrames = frameCount(); |
| 127 size_t totalBytes = 0; | 143 size_t totalBytes = 0; |
| 128 for (size_t i = 0; i < numFrames; ++i) | 144 for (size_t i = 0; i < numFrames; ++i) |
| 129 totalBytes += m_source.frameBytesAtIndex(i); | 145 totalBytes += m_source.frameBytesAtIndex(i); |
| 130 return totalBytes; | 146 return totalBytes; |
| 131 } | 147 } |
| 132 | 148 |
| 133 sk_sp<SkImage> BitmapImage::decodeAndCacheFrame(size_t index) { | 149 sk_sp<SkImage> BitmapImage::decodeAndCacheFrame( |
| 150 size_t index, |
| 151 const ColorBehavior& colorBehavior) { |
| 134 size_t numFrames = frameCount(); | 152 size_t numFrames = frameCount(); |
| 135 if (m_frames.size() < numFrames) | 153 if (m_frames.size() < numFrames) |
| 136 m_frames.grow(numFrames); | 154 m_frames.grow(numFrames); |
| 137 | 155 |
| 138 // We are caching frame snapshots. This is OK even for partially decoded | 156 // We are caching frame snapshots. This is OK even for partially decoded |
| 139 // frames, as they are cleared by dataChanged() when new data arrives. | 157 // frames, as they are cleared by dataChanged() when new data arrives. |
| 140 sk_sp<SkImage> image = m_source.createFrameAtIndex(index); | 158 sk_sp<SkImage> image = m_source.createFrameAtIndex(index, colorBehavior); |
| 141 m_cachedFrame = image; | 159 m_cachedFrame = image; |
| 142 m_cachedFrameIndex = index; | 160 m_cachedFrameIndex = index; |
| 161 m_cachedFrameColorBehavior = colorBehavior; |
| 143 | 162 |
| 144 m_frames[index].m_orientation = m_source.orientationAtIndex(index); | 163 m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
| 145 m_frames[index].m_haveMetadata = true; | 164 m_frames[index].m_haveMetadata = true; |
| 146 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); | 165 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); |
| 147 if (repetitionCount(false) != cAnimationNone) | 166 if (repetitionCount(false) != cAnimationNone) |
| 148 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); | 167 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); |
| 149 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); | 168 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| 150 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); | 169 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); |
| 151 | 170 |
| 152 notifyMemoryChanged(); | 171 notifyMemoryChanged(); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 if (m_sizeAvailable && hasVisibleImageSize(size())) { | 336 if (m_sizeAvailable && hasVisibleImageSize(size())) { |
| 318 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension()); | 337 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension()); |
| 319 if (m_source.filenameExtension() == "jpg") | 338 if (m_source.filenameExtension() == "jpg") |
| 320 BitmapImageMetrics::countImageOrientation( | 339 BitmapImageMetrics::countImageOrientation( |
| 321 m_source.orientationAtIndex(0).orientation()); | 340 m_source.orientationAtIndex(0).orientation()); |
| 322 } | 341 } |
| 323 | 342 |
| 324 return m_sizeAvailable; | 343 return m_sizeAvailable; |
| 325 } | 344 } |
| 326 | 345 |
| 327 sk_sp<SkImage> BitmapImage::frameAtIndex(size_t index) { | 346 sk_sp<SkImage> BitmapImage::frameAtIndex(size_t index, |
| 347 const ColorBehavior& colorBehavior) { |
| 328 if (index >= frameCount()) | 348 if (index >= frameCount()) |
| 329 return nullptr; | 349 return nullptr; |
| 330 | 350 |
| 331 if (index == m_cachedFrameIndex && m_cachedFrame) | 351 if (index == m_cachedFrameIndex && m_cachedFrame && |
| 352 m_cachedFrameColorBehavior == colorBehavior) |
| 332 return m_cachedFrame; | 353 return m_cachedFrame; |
| 333 | 354 |
| 334 return decodeAndCacheFrame(index); | 355 return decodeAndCacheFrame(index, colorBehavior); |
| 335 } | 356 } |
| 336 | 357 |
| 337 bool BitmapImage::frameIsCompleteAtIndex(size_t index) const { | 358 bool BitmapImage::frameIsCompleteAtIndex(size_t index) const { |
| 338 if (index < m_frames.size() && m_frames[index].m_haveMetadata && | 359 if (index < m_frames.size() && m_frames[index].m_haveMetadata && |
| 339 m_frames[index].m_isComplete) | 360 m_frames[index].m_isComplete) |
| 340 return true; | 361 return true; |
| 341 | 362 |
| 342 return m_source.frameIsCompleteAtIndex(index); | 363 return m_source.frameIsCompleteAtIndex(index); |
| 343 } | 364 } |
| 344 | 365 |
| 345 float BitmapImage::frameDurationAtIndex(size_t index) const { | 366 float BitmapImage::frameDurationAtIndex(size_t index) const { |
| 346 if (index < m_frames.size() && m_frames[index].m_haveMetadata) | 367 if (index < m_frames.size() && m_frames[index].m_haveMetadata) |
| 347 return m_frames[index].m_duration; | 368 return m_frames[index].m_duration; |
| 348 | 369 |
| 349 return m_source.frameDurationAtIndex(index); | 370 return m_source.frameDurationAtIndex(index); |
| 350 } | 371 } |
| 351 | 372 |
| 352 sk_sp<SkImage> BitmapImage::imageForCurrentFrame() { | 373 sk_sp<SkImage> BitmapImage::imageForCurrentFrame() { |
| 353 return frameAtIndex(currentFrame()); | 374 // TODO(ccameron): Allow the caller of imageForCurrentFrame to specify the |
| 375 // the desired ColorBehavior. |
| 376 // https://crbug.com/667420 |
| 377 const ColorBehavior& colorBehavior = m_cachedFrameColorBehavior; |
| 378 return frameAtIndex(currentFrame(), colorBehavior); |
| 354 } | 379 } |
| 355 | 380 |
| 356 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() { | 381 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() { |
| 382 // TODO(ccameron): Determine the appropriate ColorBehavior for this situation. |
| 383 // https://crbug.com/667420 |
| 384 const ColorBehavior& colorBehavior = m_cachedFrameColorBehavior; |
| 357 if (frameCount() > 1) { | 385 if (frameCount() > 1) { |
| 358 sk_sp<SkImage> firstFrame = frameAtIndex(0); | 386 sk_sp<SkImage> firstFrame = frameAtIndex(0, colorBehavior); |
| 359 if (firstFrame) | 387 if (firstFrame) |
| 360 return StaticBitmapImage::create(std::move(firstFrame)); | 388 return StaticBitmapImage::create(std::move(firstFrame)); |
| 361 } | 389 } |
| 362 | 390 |
| 363 return Image::imageForDefaultFrame(); | 391 return Image::imageForDefaultFrame(); |
| 364 } | 392 } |
| 365 | 393 |
| 366 bool BitmapImage::frameHasAlphaAtIndex(size_t index) { | 394 bool BitmapImage::frameHasAlphaAtIndex(size_t index) { |
| 367 if (m_frames.size() <= index) | 395 if (m_frames.size() <= index) |
| 368 return true; | 396 return true; |
| 369 | 397 |
| 370 if (m_frames[index].m_haveMetadata && !m_frames[index].m_hasAlpha) | 398 if (m_frames[index].m_haveMetadata && !m_frames[index].m_hasAlpha) |
| 371 return false; | 399 return false; |
| 372 | 400 |
| 373 // m_hasAlpha may change after m_haveMetadata is set to true, so always ask | 401 // m_hasAlpha may change after m_haveMetadata is set to true, so always ask |
| 374 // ImageSource for the value if the cached value is the default value. | 402 // ImageSource for the value if the cached value is the default value. |
| 375 bool hasAlpha = m_source.frameHasAlphaAtIndex(index); | 403 bool hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| 376 | 404 |
| 377 if (m_frames[index].m_haveMetadata) | 405 if (m_frames[index].m_haveMetadata) |
| 378 m_frames[index].m_hasAlpha = hasAlpha; | 406 m_frames[index].m_hasAlpha = hasAlpha; |
| 379 | 407 |
| 380 return hasAlpha; | 408 return hasAlpha; |
| 381 } | 409 } |
| 382 | 410 |
| 383 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) { | 411 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) { |
| 384 if (metadataMode == PreCacheMetadata) { | 412 if (metadataMode == PreCacheMetadata) { |
| 385 // frameHasAlphaAtIndex() conservatively returns false for uncached frames. | 413 // frameHasAlphaAtIndex() conservatively returns false for uncached frames. |
| 386 // To increase the chance of an accurate answer, pre-cache the current frame | 414 // To increase the chance of an accurate answer, pre-cache the current frame |
| 387 // metadata. | 415 // metadata. Because ColorBehavior does not affect this result, use |
| 388 frameAtIndex(currentFrame()); | 416 // whatever ColorBehavior was last used (if any). |
| 417 frameAtIndex(currentFrame(), m_cachedFrameColorBehavior); |
| 389 } | 418 } |
| 390 return !frameHasAlphaAtIndex(currentFrame()); | 419 return !frameHasAlphaAtIndex(currentFrame()); |
| 391 } | 420 } |
| 392 | 421 |
| 393 bool BitmapImage::currentFrameIsComplete() { | 422 bool BitmapImage::currentFrameIsComplete() { |
| 394 return frameIsCompleteAtIndex(currentFrame()); | 423 return frameIsCompleteAtIndex(currentFrame()); |
| 395 } | 424 } |
| 396 | 425 |
| 397 bool BitmapImage::currentFrameIsLazyDecoded() { | 426 bool BitmapImage::currentFrameIsLazyDecoded() { |
| 398 sk_sp<SkImage> image = frameAtIndex(currentFrame()); | 427 // Because ColorBehavior does not affect this result, use whatever |
| 428 // ColorBehavior was last used (if any). |
| 429 sk_sp<SkImage> image = |
| 430 frameAtIndex(currentFrame(), m_cachedFrameColorBehavior); |
| 399 return image && image->isLazyGenerated(); | 431 return image && image->isLazyGenerated(); |
| 400 } | 432 } |
| 401 | 433 |
| 402 ImageOrientation BitmapImage::currentFrameOrientation() { | 434 ImageOrientation BitmapImage::currentFrameOrientation() { |
| 403 return frameOrientationAtIndex(currentFrame()); | 435 return frameOrientationAtIndex(currentFrame()); |
| 404 } | 436 } |
| 405 | 437 |
| 406 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) { | 438 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) { |
| 407 if (m_frames.size() <= index) | 439 if (m_frames.size() <= index) |
| 408 return DefaultImageOrientation; | 440 return DefaultImageOrientation; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 getImageObserver()->animationAdvanced(this); | 653 getImageObserver()->animationAdvanced(this); |
| 622 | 654 |
| 623 return true; | 655 return true; |
| 624 } | 656 } |
| 625 | 657 |
| 626 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) { | 658 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) { |
| 627 getImageObserver()->animationAdvanced(this); | 659 getImageObserver()->animationAdvanced(this); |
| 628 } | 660 } |
| 629 | 661 |
| 630 } // namespace blink | 662 } // namespace blink |
| OLD | NEW |