Chromium Code Reviews| 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 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 , m_haveSize(false) | 70 , m_haveSize(false) |
| 71 , m_sizeAvailable(false) | 71 , m_sizeAvailable(false) |
| 72 , m_haveFrameCount(false) | 72 , m_haveFrameCount(false) |
| 73 { | 73 { |
| 74 } | 74 } |
| 75 | 75 |
| 76 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) | 76 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
| 77 : Image(observer) | 77 : Image(observer) |
| 78 , m_size(bitmap.width(), bitmap.height()) | 78 , m_size(bitmap.width(), bitmap.height()) |
| 79 , m_currentFrame(0) | 79 , m_currentFrame(0) |
| 80 , m_cachedFrame(fromSkSp(SkImage::MakeFromBitmap(bitmap))) | 80 , m_cachedFrame(SkImage::MakeFromBitmap(bitmap)) |
| 81 , m_cachedFrameIndex(0) | 81 , m_cachedFrameIndex(0) |
| 82 , m_repetitionCount(cAnimationNone) | 82 , m_repetitionCount(cAnimationNone) |
| 83 , m_repetitionCountStatus(Unknown) | 83 , m_repetitionCountStatus(Unknown) |
| 84 , m_repetitionsComplete(0) | 84 , m_repetitionsComplete(0) |
| 85 , m_frameCount(1) | 85 , m_frameCount(1) |
| 86 , m_animationPolicy(ImageAnimationPolicyAllowed) | 86 , m_animationPolicy(ImageAnimationPolicyAllowed) |
| 87 , m_animationFinished(true) | 87 , m_animationFinished(true) |
| 88 , m_allDataReceived(true) | 88 , m_allDataReceived(true) |
| 89 , m_haveSize(true) | 89 , m_haveSize(true) |
| 90 , m_sizeAvailable(true) | 90 , m_sizeAvailable(true) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 104 stopAnimation(); | 104 stopAnimation(); |
| 105 } | 105 } |
| 106 | 106 |
| 107 bool BitmapImage::currentFrameHasSingleSecurityOrigin() const | 107 bool BitmapImage::currentFrameHasSingleSecurityOrigin() const |
| 108 { | 108 { |
| 109 return true; | 109 return true; |
| 110 } | 110 } |
| 111 | 111 |
| 112 void BitmapImage::destroyDecodedData() | 112 void BitmapImage::destroyDecodedData() |
| 113 { | 113 { |
| 114 m_cachedFrame.clear(); | 114 m_cachedFrame.reset(); |
| 115 for (size_t i = 0; i < m_frames.size(); ++i) | 115 for (size_t i = 0; i < m_frames.size(); ++i) |
| 116 m_frames[i].clear(true); | 116 m_frames[i].clear(true); |
| 117 m_source.clearCacheExceptFrame(kNotFound); | 117 m_source.clearCacheExceptFrame(kNotFound); |
| 118 notifyMemoryChanged(); | 118 notifyMemoryChanged(); |
| 119 } | 119 } |
| 120 | 120 |
| 121 PassRefPtr<SharedBuffer> BitmapImage::data() | 121 PassRefPtr<SharedBuffer> BitmapImage::data() |
| 122 { | 122 { |
| 123 return m_source.data(); | 123 return m_source.data(); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void BitmapImage::notifyMemoryChanged() | 126 void BitmapImage::notifyMemoryChanged() |
| 127 { | 127 { |
| 128 if (getImageObserver()) | 128 if (getImageObserver()) |
| 129 getImageObserver()->decodedSizeChangedTo(this, totalFrameBytes()); | 129 getImageObserver()->decodedSizeChangedTo(this, totalFrameBytes()); |
| 130 } | 130 } |
| 131 | 131 |
| 132 size_t BitmapImage::totalFrameBytes() | 132 size_t BitmapImage::totalFrameBytes() |
| 133 { | 133 { |
| 134 const size_t numFrames = frameCount(); | 134 const size_t numFrames = frameCount(); |
| 135 size_t totalBytes = 0; | 135 size_t totalBytes = 0; |
| 136 for (size_t i = 0; i < numFrames; ++i) | 136 for (size_t i = 0; i < numFrames; ++i) |
| 137 totalBytes += m_source.frameBytesAtIndex(i); | 137 totalBytes += m_source.frameBytesAtIndex(i); |
| 138 return totalBytes; | 138 return totalBytes; |
| 139 } | 139 } |
| 140 | 140 |
| 141 PassRefPtr<SkImage> BitmapImage::decodeAndCacheFrame(size_t index) | 141 sk_sp<SkImage> BitmapImage::decodeAndCacheFrame(size_t index) |
| 142 { | 142 { |
| 143 size_t numFrames = frameCount(); | 143 size_t numFrames = frameCount(); |
| 144 if (m_frames.size() < numFrames) | 144 if (m_frames.size() < numFrames) |
| 145 m_frames.grow(numFrames); | 145 m_frames.grow(numFrames); |
| 146 | 146 |
| 147 // We are caching frame snapshots. This is OK even for partially decoded fr ames, | 147 // We are caching frame snapshots. This is OK even for partially decoded fr ames, |
| 148 // as they are cleared by dataChanged() when new data arrives. | 148 // as they are cleared by dataChanged() when new data arrives. |
| 149 RefPtr<SkImage> image = m_source.createFrameAtIndex(index); | 149 sk_sp<SkImage> image = m_source.createFrameAtIndex(index); |
| 150 m_cachedFrame = image; | 150 m_cachedFrame = image; |
| 151 m_cachedFrameIndex = index; | 151 m_cachedFrameIndex = index; |
| 152 | 152 |
| 153 m_frames[index].m_orientation = m_source.orientationAtIndex(index); | 153 m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
| 154 m_frames[index].m_haveMetadata = true; | 154 m_frames[index].m_haveMetadata = true; |
| 155 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); | 155 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); |
| 156 if (repetitionCount(false) != cAnimationNone) | 156 if (repetitionCount(false) != cAnimationNone) |
| 157 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); | 157 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); |
| 158 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); | 158 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| 159 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); | 159 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); |
| 160 | 160 |
| 161 notifyMemoryChanged(); | 161 notifyMemoryChanged(); |
| 162 return image.release(); | 162 return image; |
| 163 } | 163 } |
| 164 | 164 |
| 165 void BitmapImage::updateSize() const | 165 void BitmapImage::updateSize() const |
| 166 { | 166 { |
| 167 if (!m_sizeAvailable || m_haveSize) | 167 if (!m_sizeAvailable || m_haveSize) |
| 168 return; | 168 return; |
| 169 | 169 |
| 170 m_size = m_source.size(); | 170 m_size = m_source.size(); |
| 171 m_sizeRespectingOrientation = m_source.size(RespectImageOrientation); | 171 m_sizeRespectingOrientation = m_source.size(RespectImageOrientation); |
| 172 m_haveSize = true; | 172 m_haveSize = true; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 // start of the frame data), and any or none of them might be the particular | 227 // start of the frame data), and any or none of them might be the particular |
| 228 // frame affected by appending new data here. Thus we have to clear all the | 228 // frame affected by appending new data here. Thus we have to clear all the |
| 229 // incomplete frames to be safe. | 229 // incomplete frames to be safe. |
| 230 for (size_t i = 0; i < m_frames.size(); ++i) { | 230 for (size_t i = 0; i < m_frames.size(); ++i) { |
| 231 // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to | 231 // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to |
| 232 // decode any uncached (i.e. never-decoded or | 232 // decode any uncached (i.e. never-decoded or |
| 233 // cleared-on-a-previous-pass) frames! | 233 // cleared-on-a-previous-pass) frames! |
| 234 if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) { | 234 if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) { |
| 235 m_frames[i].clear(true); | 235 m_frames[i].clear(true); |
| 236 if (i == m_cachedFrameIndex) | 236 if (i == m_cachedFrameIndex) |
| 237 m_cachedFrame.clear(); | 237 m_cachedFrame.reset(); |
| 238 } | 238 } |
| 239 } | 239 } |
| 240 | 240 |
| 241 // Feed all the data we've seen so far to the image decoder. | 241 // Feed all the data we've seen so far to the image decoder. |
| 242 m_allDataReceived = allDataReceived; | 242 m_allDataReceived = allDataReceived; |
| 243 | 243 |
| 244 m_haveFrameCount = false; | 244 m_haveFrameCount = false; |
| 245 return isSizeAvailable() ? SizeAvailable : SizeUnavailable; | 245 return isSizeAvailable() ? SizeAvailable : SizeUnavailable; |
| 246 } | 246 } |
| 247 | 247 |
| 248 bool BitmapImage::hasColorProfile() const | 248 bool BitmapImage::hasColorProfile() const |
| 249 { | 249 { |
| 250 return m_source.hasColorProfile(); | 250 return m_source.hasColorProfile(); |
| 251 } | 251 } |
| 252 | 252 |
| 253 String BitmapImage::filenameExtension() const | 253 String BitmapImage::filenameExtension() const |
| 254 { | 254 { |
| 255 return m_source.filenameExtension(); | 255 return m_source.filenameExtension(); |
| 256 } | 256 } |
| 257 | 257 |
| 258 void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dstRect, const FloatRect& srcRect, RespectImageOrientationEnum shouldRespectImag eOrientation, ImageClampingMode clampMode) | 258 void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dstRect, const FloatRect& srcRect, RespectImageOrientationEnum shouldRespectImag eOrientation, ImageClampingMode clampMode) |
| 259 { | 259 { |
| 260 TRACE_EVENT0("skia", "BitmapImage::draw"); | 260 TRACE_EVENT0("skia", "BitmapImage::draw"); |
| 261 | 261 |
| 262 RefPtr<SkImage> image = imageForCurrentFrame(); | 262 sk_sp<SkImage> image = imageForCurrentFrame(); |
| 263 if (!image) | 263 if (!image) |
| 264 return; // It's too early and we don't have an image yet. | 264 return; // It's too early and we don't have an image yet. |
| 265 | 265 |
| 266 FloatRect adjustedSrcRect = srcRect; | 266 FloatRect adjustedSrcRect = srcRect; |
| 267 adjustedSrcRect.intersect(SkRect::Make(image->bounds())); | 267 adjustedSrcRect.intersect(SkRect::Make(image->bounds())); |
| 268 | 268 |
| 269 if (adjustedSrcRect.isEmpty() || dstRect.isEmpty()) | 269 if (adjustedSrcRect.isEmpty() || dstRect.isEmpty()) |
| 270 return; // Nothing to draw. | 270 return; // Nothing to draw. |
| 271 | 271 |
| 272 ImageOrientation orientation = DefaultImageOrientation; | 272 ImageOrientation orientation = DefaultImageOrientation; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 | 329 |
| 330 if (m_sizeAvailable && hasVisibleImageSize(size())) { | 330 if (m_sizeAvailable && hasVisibleImageSize(size())) { |
| 331 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension()); | 331 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension()); |
| 332 if (m_source.filenameExtension() == "jpg") | 332 if (m_source.filenameExtension() == "jpg") |
| 333 BitmapImageMetrics::countImageOrientation(m_source.orientationAtInde x(0).orientation()); | 333 BitmapImageMetrics::countImageOrientation(m_source.orientationAtInde x(0).orientation()); |
| 334 } | 334 } |
| 335 | 335 |
| 336 return m_sizeAvailable; | 336 return m_sizeAvailable; |
| 337 } | 337 } |
| 338 | 338 |
| 339 PassRefPtr<SkImage> BitmapImage::frameAtIndex(size_t index) | 339 sk_sp<SkImage> BitmapImage::frameAtIndex(size_t index) |
| 340 { | 340 { |
| 341 if (index >= frameCount()) | 341 if (index >= frameCount()) |
| 342 return nullptr; | 342 return nullptr; |
| 343 | 343 |
| 344 if (index == m_cachedFrameIndex && m_cachedFrame) | 344 if (index == m_cachedFrameIndex && m_cachedFrame) |
| 345 return m_cachedFrame; | 345 return m_cachedFrame; |
| 346 | 346 |
| 347 return decodeAndCacheFrame(index); | 347 return decodeAndCacheFrame(index); |
| 348 } | 348 } |
| 349 | 349 |
| 350 bool BitmapImage::frameIsCompleteAtIndex(size_t index) | 350 bool BitmapImage::frameIsCompleteAtIndex(size_t index) |
| 351 { | 351 { |
| 352 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in dex].m_isComplete) | 352 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in dex].m_isComplete) |
| 353 return true; | 353 return true; |
| 354 | 354 |
| 355 return m_source.frameIsCompleteAtIndex(index); | 355 return m_source.frameIsCompleteAtIndex(index); |
| 356 } | 356 } |
| 357 | 357 |
| 358 float BitmapImage::frameDurationAtIndex(size_t index) | 358 float BitmapImage::frameDurationAtIndex(size_t index) |
| 359 { | 359 { |
| 360 if (index < m_frames.size() && m_frames[index].m_haveMetadata) | 360 if (index < m_frames.size() && m_frames[index].m_haveMetadata) |
| 361 return m_frames[index].m_duration; | 361 return m_frames[index].m_duration; |
| 362 | 362 |
| 363 return m_source.frameDurationAtIndex(index); | 363 return m_source.frameDurationAtIndex(index); |
| 364 } | 364 } |
| 365 | 365 |
| 366 PassRefPtr<SkImage> BitmapImage::imageForCurrentFrame() | 366 sk_sp<SkImage> BitmapImage::imageForCurrentFrame() |
| 367 { | 367 { |
| 368 return frameAtIndex(currentFrame()); | 368 return frameAtIndex(currentFrame()); |
| 369 } | 369 } |
| 370 | 370 |
| 371 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() | 371 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() |
| 372 { | 372 { |
| 373 if (frameCount() > 1) { | 373 if (frameCount() > 1) { |
| 374 RefPtr<SkImage> firstFrame = frameAtIndex(0); | 374 sk_sp<SkImage> firstFrame = frameAtIndex(0); |
| 375 if (firstFrame) | 375 if (firstFrame) |
| 376 return StaticBitmapImage::create(firstFrame); | 376 return StaticBitmapImage::create(firstFrame); |
|
f(malita)
2016/09/01 03:55:38
not new to this CL, but std::move(firstFrame) make
Łukasz Anforowicz
2016/09/01 20:50:58
Good catch. Done.
| |
| 377 } | 377 } |
| 378 | 378 |
| 379 return Image::imageForDefaultFrame(); | 379 return Image::imageForDefaultFrame(); |
| 380 } | 380 } |
| 381 | 381 |
| 382 bool BitmapImage::frameHasAlphaAtIndex(size_t index) | 382 bool BitmapImage::frameHasAlphaAtIndex(size_t index) |
| 383 { | 383 { |
| 384 if (m_frames.size() <= index) | 384 if (m_frames.size() <= index) |
| 385 return true; | 385 return true; |
| 386 | 386 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 407 return !frameHasAlphaAtIndex(currentFrame()); | 407 return !frameHasAlphaAtIndex(currentFrame()); |
| 408 } | 408 } |
| 409 | 409 |
| 410 bool BitmapImage::currentFrameIsComplete() | 410 bool BitmapImage::currentFrameIsComplete() |
| 411 { | 411 { |
| 412 return frameIsCompleteAtIndex(currentFrame()); | 412 return frameIsCompleteAtIndex(currentFrame()); |
| 413 } | 413 } |
| 414 | 414 |
| 415 bool BitmapImage::currentFrameIsLazyDecoded() | 415 bool BitmapImage::currentFrameIsLazyDecoded() |
| 416 { | 416 { |
| 417 RefPtr<SkImage> image = frameAtIndex(currentFrame()); | 417 sk_sp<SkImage> image = frameAtIndex(currentFrame()); |
| 418 return image && image->isLazyGenerated(); | 418 return image && image->isLazyGenerated(); |
| 419 } | 419 } |
| 420 | 420 |
| 421 ImageOrientation BitmapImage::currentFrameOrientation() | 421 ImageOrientation BitmapImage::currentFrameOrientation() |
| 422 { | 422 { |
| 423 return frameOrientationAtIndex(currentFrame()); | 423 return frameOrientationAtIndex(currentFrame()); |
| 424 } | 424 } |
| 425 | 425 |
| 426 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) | 426 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) |
| 427 { | 427 { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 m_frameTimer.reset(); | 545 m_frameTimer.reset(); |
| 546 } | 546 } |
| 547 | 547 |
| 548 void BitmapImage::resetAnimation() | 548 void BitmapImage::resetAnimation() |
| 549 { | 549 { |
| 550 stopAnimation(); | 550 stopAnimation(); |
| 551 m_currentFrame = 0; | 551 m_currentFrame = 0; |
| 552 m_repetitionsComplete = 0; | 552 m_repetitionsComplete = 0; |
| 553 m_desiredFrameStartTime = 0; | 553 m_desiredFrameStartTime = 0; |
| 554 m_animationFinished = false; | 554 m_animationFinished = false; |
| 555 m_cachedFrame.clear(); | 555 m_cachedFrame.reset(); |
| 556 } | 556 } |
| 557 | 557 |
| 558 bool BitmapImage::maybeAnimated() | 558 bool BitmapImage::maybeAnimated() |
| 559 { | 559 { |
| 560 if (m_animationFinished) | 560 if (m_animationFinished) |
| 561 return false; | 561 return false; |
| 562 if (frameCount() > 1) | 562 if (frameCount() > 1) |
| 563 return true; | 563 return true; |
| 564 | 564 |
| 565 return m_source.repetitionCount() != cAnimationNone; | 565 return m_source.repetitionCount() != cAnimationNone; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 | 635 |
| 636 return true; | 636 return true; |
| 637 } | 637 } |
| 638 | 638 |
| 639 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) | 639 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) |
| 640 { | 640 { |
| 641 getImageObserver()->animationAdvanced(this); | 641 getImageObserver()->animationAdvanced(this); |
| 642 } | 642 } |
| 643 | 643 |
| 644 } // namespace blink | 644 } // namespace blink |
| OLD | NEW |