1/* 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 25 */ 26 27#include "config.h" 28#include "BitmapImage.h" 29 30#include "FloatRect.h" 31#include "ImageObserver.h" 32#include "IntRect.h" 33#include "MIMETypeRegistry.h" 34#include "Timer.h" 35#include <wtf/CurrentTime.h> 36#include <wtf/Vector.h> 37#include <wtf/text/WTFString.h> 38 39namespace WebCore { 40 41BitmapImage::BitmapImage(ImageObserver* observer) 42 : Image(observer) 43 , m_currentFrame(0) 44 , m_frames(0) 45 , m_frameTimer(0) 46 , m_repetitionCount(cAnimationNone) 47 , m_repetitionCountStatus(Unknown) 48 , m_repetitionsComplete(0) 49 , m_desiredFrameStartTime(0) 50 , m_decodedSize(0) 51 , m_decodedPropertiesSize(0) 52 , m_frameCount(0) 53 , m_isSolidColor(false) 54 , m_checkedForSolidColor(false) 55 , m_animationFinished(false) 56 , m_allDataReceived(false) 57 , m_haveSize(false) 58 , m_sizeAvailable(false) 59 , m_hasUniformFrameSize(true) 60 , m_haveFrameCount(false) 61{ 62} 63 64BitmapImage::~BitmapImage() 65{ 66 invalidatePlatformData(); 67 stopAnimation(); 68} 69 70bool BitmapImage::isBitmapImage() const 71{ 72 return true; 73} 74 75bool BitmapImage::hasSingleSecurityOrigin() const 76{ 77 return true; 78} 79 80 81void BitmapImage::destroyDecodedData(bool destroyAll) 82{ 83 unsigned frameBytesCleared = 0; 84 const size_t clearBeforeFrame = destroyAll ? m_frames.size() : m_currentFrame; 85 for (size_t i = 0; i < clearBeforeFrame; ++i) { 86 // The underlying frame isn't actually changing (we're just trying to 87 // save the memory for the framebuffer data), so we don't need to clear 88 // the metadata. 89 unsigned frameBytes = m_frames[i].m_frameBytes; 90 if (m_frames[i].clear(false)) 91 frameBytesCleared += frameBytes; 92 } 93 94 destroyMetadataAndNotify(frameBytesCleared); 95 96 m_source.clear(destroyAll, clearBeforeFrame, data(), m_allDataReceived); 97 return; 98} 99 100void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll) 101{ 102 // Animated images >5MB are considered large enough that we'll only hang on 103 // to one frame at a time. 104 static const unsigned cLargeAnimationCutoff = 5242880; 105 unsigned allFrameBytes = 0; 106 for (size_t i = 0; i < m_frames.size(); ++i) 107 allFrameBytes += m_frames[i].m_frameBytes; 108 109 if (allFrameBytes > cLargeAnimationCutoff) 110 destroyDecodedData(destroyAll); 111} 112 113void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared) 114{ 115 m_isSolidColor = false; 116 m_checkedForSolidColor = false; 117 invalidatePlatformData(); 118 119 ASSERT(m_decodedSize >= frameBytesCleared); 120 m_decodedSize -= frameBytesCleared; 121 if (frameBytesCleared > 0) { 122 frameBytesCleared += m_decodedPropertiesSize; 123 m_decodedPropertiesSize = 0; 124 } 125 if (frameBytesCleared && imageObserver()) 126 imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesCleared)); 127} 128 129void BitmapImage::cacheFrame(size_t index) 130{ 131 size_t numFrames = frameCount(); 132 ASSERT(m_decodedSize == 0 || numFrames > 1); 133 134 if (m_frames.size() < numFrames) 135 m_frames.grow(numFrames); 136 137 m_frames[index].m_frame = m_source.createFrameAtIndex(index); 138 if (numFrames == 1 && m_frames[index].m_frame) 139 checkForSolidColor(); 140 141 m_frames[index].m_orientation = m_source.orientationAtIndex(index); 142 m_frames[index].m_haveMetadata = true; 143 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); 144 if (repetitionCount(false) != cAnimationNone) 145 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); 146 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); 147 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); 148 149 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); 150 if (frameSize != m_size) 151 m_hasUniformFrameSize = false; 152 if (m_frames[index].m_frame) { 153 int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes); 154 m_decodedSize += deltaBytes; 155 // The fully-decoded frame will subsume the partially decoded data used 156 // to determine image properties. 157 deltaBytes -= m_decodedPropertiesSize; 158 m_decodedPropertiesSize = 0; 159 if (imageObserver()) 160 imageObserver()->decodedSizeChanged(this, deltaBytes); 161 } 162} 163 164void BitmapImage::didDecodeProperties() const 165{ 166 if (m_decodedSize) 167 return; 168 size_t updatedSize = m_source.bytesDecodedToDetermineProperties(); 169 if (m_decodedPropertiesSize == updatedSize) 170 return; 171 int deltaBytes = updatedSize - m_decodedPropertiesSize; 172#if !ASSERT_DISABLED 173 bool overflow = updatedSize > m_decodedPropertiesSize && deltaBytes < 0; 174 bool underflow = updatedSize < m_decodedPropertiesSize && deltaBytes > 0; 175 ASSERT(!overflow && !underflow); 176#endif 177 m_decodedPropertiesSize = updatedSize; 178 if (imageObserver()) 179 imageObserver()->decodedSizeChanged(this, deltaBytes); 180} 181 182void BitmapImage::updateSize() const 183{ 184 if (!m_sizeAvailable || m_haveSize) 185 return; 186 187 m_size = m_source.size(); 188 m_sizeRespectingOrientation = m_source.size(RespectImageOrientation); 189 m_haveSize = true; 190 didDecodeProperties(); 191} 192 193IntSize BitmapImage::size() const 194{ 195 updateSize(); 196 return m_size; 197} 198 199IntSize BitmapImage::sizeRespectingOrientation() const 200{ 201 updateSize(); 202 return m_sizeRespectingOrientation; 203} 204 205IntSize BitmapImage::currentFrameSize() const 206{ 207 if (!m_currentFrame || m_hasUniformFrameSize) 208 return size(); 209 IntSize frameSize = m_source.frameSizeAtIndex(m_currentFrame); 210 didDecodeProperties(); 211 return frameSize; 212} 213 214bool BitmapImage::getHotSpot(IntPoint& hotSpot) const 215{ 216 bool result = m_source.getHotSpot(hotSpot); 217 didDecodeProperties(); 218 return result; 219} 220 221bool BitmapImage::dataChanged(bool allDataReceived) 222{ 223 // Clear all partially-decoded frames. For most image formats, there is only 224 // one frame, but at least GIF and ICO can have more. With GIFs, the frames 225 // come in order and we ask to decode them in order, waiting to request a 226 // subsequent frame until the prior one is complete. Given that we clear 227 // incomplete frames here, this means there is at most one incomplete frame 228 // (even if we use destroyDecodedData() -- since it doesn't reset the 229 // metadata), and it is after all the complete frames. 230 // 231 // With ICOs, on the other hand, we may ask for arbitrary frames at 232 // different times (e.g. because we're displaying a higher-resolution image 233 // in the content area and using a lower-resolution one for the favicon), 234 // and the frames aren't even guaranteed to appear in the file in the same 235 // order as in the directory, so an arbitrary number of the frames might be 236 // incomplete (if we ask for frames for which we've not yet reached the 237 // start of the frame data), and any or none of them might be the particular 238 // frame affected by appending new data here. Thus we have to clear all the 239 // incomplete frames to be safe. 240 unsigned frameBytesCleared = 0; 241 for (size_t i = 0; i < m_frames.size(); ++i) { 242 // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to 243 // decode any uncached (i.e. never-decoded or 244 // cleared-on-a-previous-pass) frames! 245 unsigned frameBytes = m_frames[i].m_frameBytes; 246 if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) 247 frameBytesCleared += (m_frames[i].clear(true) ? frameBytes : 0); 248 } 249 destroyMetadataAndNotify(frameBytesCleared); 250 251 // Feed all the data we've seen so far to the image decoder. 252 m_allDataReceived = allDataReceived; 253 m_source.setData(data(), allDataReceived); 254 255 m_haveFrameCount = false; 256 m_hasUniformFrameSize = true; 257 return isSizeAvailable(); 258} 259 260String BitmapImage::filenameExtension() const 261{ 262 return m_source.filenameExtension(); 263} 264 265size_t BitmapImage::frameCount() 266{ 267 if (!m_haveFrameCount) { 268 m_frameCount = m_source.frameCount(); 269 // If decoder is not initialized yet, m_source.frameCount() returns 0. 270 if (m_frameCount) { 271 didDecodeProperties(); 272 m_haveFrameCount = true; 273 } 274 } 275 return m_frameCount; 276} 277 278bool BitmapImage::isSizeAvailable() 279{ 280 if (m_sizeAvailable) 281 return true; 282 283 m_sizeAvailable = m_source.isSizeAvailable(); 284 didDecodeProperties(); 285 286 return m_sizeAvailable; 287} 288 289bool BitmapImage::ensureFrameIsCached(size_t index) 290{ 291 if (index >= frameCount()) 292 return false; 293 294 if (index >= m_frames.size() || !m_frames[index].m_frame) 295 cacheFrame(index); 296 return true; 297} 298 299PassNativeImagePtr BitmapImage::frameAtIndex(size_t index) 300{ 301 if (!ensureFrameIsCached(index)) 302 return 0; 303 return m_frames[index].m_frame; 304} 305 306bool BitmapImage::frameIsCompleteAtIndex(size_t index) 307{ 308 if (!ensureFrameIsCached(index)) 309 return false; 310 return m_frames[index].m_isComplete; 311} 312 313float BitmapImage::frameDurationAtIndex(size_t index) 314{ 315 if (!ensureFrameIsCached(index)) 316 return 0; 317 return m_frames[index].m_duration; 318} 319 320PassNativeImagePtr BitmapImage::nativeImageForCurrentFrame() 321{ 322 return frameAtIndex(currentFrame()); 323} 324 325bool BitmapImage::frameHasAlphaAtIndex(size_t index) 326{ 327 if (m_frames.size() <= index) 328 return true; 329 330 if (m_frames[index].m_haveMetadata) 331 return m_frames[index].m_hasAlpha; 332 333 return m_source.frameHasAlphaAtIndex(index); 334} 335 336bool BitmapImage::currentFrameKnownToBeOpaque() 337{ 338 return !frameHasAlphaAtIndex(currentFrame()); 339} 340 341ImageOrientation BitmapImage::currentFrameOrientation() 342{ 343 return frameOrientationAtIndex(currentFrame()); 344} 345 346ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) 347{ 348 if (m_frames.size() <= index) 349 return DefaultImageOrientation; 350 351 if (m_frames[index].m_haveMetadata) 352 return m_frames[index].m_orientation; 353 354 return m_source.orientationAtIndex(index); 355} 356 357#if !ASSERT_DISABLED 358bool BitmapImage::notSolidColor() 359{ 360 return size().width() != 1 || size().height() != 1 || frameCount() > 1; 361} 362#endif 363 364 365 366int BitmapImage::repetitionCount(bool imageKnownToBeComplete) 367{ 368 if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Uncertain) && imageKnownToBeComplete)) { 369 // Snag the repetition count. If |imageKnownToBeComplete| is false, the 370 // repetition count may not be accurate yet for GIFs; in this case the 371 // decoder will default to cAnimationLoopOnce, and we'll try and read 372 // the count again once the whole image is decoded. 373 m_repetitionCount = m_source.repetitionCount(); 374 didDecodeProperties(); 375 m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == cAnimationNone) ? Certain : Uncertain; 376 } 377 return m_repetitionCount; 378} 379 380bool BitmapImage::shouldAnimate() 381{ 382 return (repetitionCount(false) != cAnimationNone && !m_animationFinished && imageObserver()); 383} 384 385void BitmapImage::startAnimation(bool catchUpIfNecessary) 386{ 387 if (m_frameTimer || !shouldAnimate() || frameCount() <= 1) 388 return; 389 390 // If we aren't already animating, set now as the animation start time. 391 const double time = monotonicallyIncreasingTime(); 392 if (!m_desiredFrameStartTime) 393 m_desiredFrameStartTime = time; 394 395 // Don't advance the animation to an incomplete frame. 396 size_t nextFrame = (m_currentFrame + 1) % frameCount(); 397 if (!m_allDataReceived && !frameIsCompleteAtIndex(nextFrame)) 398 return; 399 400 // Don't advance past the last frame if we haven't decoded the whole image 401 // yet and our repetition count is potentially unset. The repetition count 402 // in a GIF can potentially come after all the rest of the image data, so 403 // wait on it. 404 if (!m_allDataReceived && repetitionCount(false) == cAnimationLoopOnce && m_currentFrame >= (frameCount() - 1)) 405 return; 406 407 // Determine time for next frame to start. By ignoring paint and timer lag 408 // in this calculation, we make the animation appear to run at its desired 409 // rate regardless of how fast it's being repainted. 410 const double currentDuration = frameDurationAtIndex(m_currentFrame); 411 m_desiredFrameStartTime += currentDuration; 412 413 // When an animated image is more than five minutes out of date, the 414 // user probably doesn't care about resyncing and we could burn a lot of 415 // time looping through frames below. Just reset the timings. 416 const double cAnimationResyncCutoff = 5 * 60; 417 if ((time - m_desiredFrameStartTime) > cAnimationResyncCutoff) 418 m_desiredFrameStartTime = time + currentDuration; 419 420 // The image may load more slowly than it's supposed to animate, so that by 421 // the time we reach the end of the first repetition, we're well behind. 422 // Clamp the desired frame start time in this case, so that we don't skip 423 // frames (or whole iterations) trying to "catch up". This is a tradeoff: 424 // It guarantees users see the whole animation the second time through and 425 // don't miss any repetitions, and is closer to what other browsers do; on 426 // the other hand, it makes animations "less accurate" for pages that try to 427 // sync an image and some other resource (e.g. audio), especially if users 428 // switch tabs (and thus stop drawing the animation, which will pause it) 429 // during that initial loop, then switch back later. 430 if (nextFrame == 0 && m_repetitionsComplete == 0 && m_desiredFrameStartTime < time) 431 m_desiredFrameStartTime = time; 432 433 if (!catchUpIfNecessary || time < m_desiredFrameStartTime) { 434 // Haven't yet reached time for next frame to start; delay until then. 435 m_frameTimer = new Timer<BitmapImage>(this, &BitmapImage::advanceAnimation); 436 m_frameTimer->startOneShot(std::max(m_desiredFrameStartTime - time, 0.)); 437 } else { 438 // We've already reached or passed the time for the next frame to start. 439 // See if we've also passed the time for frames after that to start, in 440 // case we need to skip some frames entirely. Remember not to advance 441 // to an incomplete frame. 442 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsCompleteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) { 443 // Should we skip the next frame? 444 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDurationAtIndex(nextFrame); 445 if (time < frameAfterNextStartTime) 446 break; 447 448 // Yes; skip over it without notifying our observers. 449 if (!internalAdvanceAnimation(true)) 450 return; 451 m_desiredFrameStartTime = frameAfterNextStartTime; 452 nextFrame = frameAfterNext; 453 } 454 455 // Draw the next frame immediately. Note that m_desiredFrameStartTime 456 // may be in the past, meaning the next time through this function we'll 457 // kick off the next advancement sooner than this frame's duration would 458 // suggest. 459 if (internalAdvanceAnimation(false)) { 460 // The image region has been marked dirty, but once we return to our 461 // caller, draw() will clear it, and nothing will cause the 462 // animation to advance again. We need to start the timer for the 463 // next frame running, or the animation can hang. (Compare this 464 // with when advanceAnimation() is called, and the region is dirtied 465 // while draw() is not in the callstack, meaning draw() gets called 466 // to update the region and thus startAnimation() is reached again.) 467 // NOTE: For large images with slow or heavily-loaded systems, 468 // throwing away data as we go (see destroyDecodedData()) means we 469 // can spend so much time re-decoding data above that by the time we 470 // reach here we're behind again. If we let startAnimation() run 471 // the catch-up code again, we can get long delays without painting 472 // as we race the timer, or even infinite recursion. In this 473 // situation the best we can do is to simply change frames as fast 474 // as possible, so force startAnimation() to set a zero-delay timer 475 // and bail out if we're not caught up. 476 startAnimation(false); 477 } 478 } 479} 480 481void BitmapImage::stopAnimation() 482{ 483 // This timer is used to animate all occurrences of this image. Don't invalidate 484 // the timer unless all renderers have stopped drawing. 485 delete m_frameTimer; 486 m_frameTimer = 0; 487} 488 489void BitmapImage::resetAnimation() 490{ 491 stopAnimation(); 492 m_currentFrame = 0; 493 m_repetitionsComplete = 0; 494 m_desiredFrameStartTime = 0; 495 m_animationFinished = false; 496 497 // For extremely large animations, when the animation is reset, we just throw everything away. 498 destroyDecodedDataIfNecessary(true); 499} 500 501unsigned BitmapImage::decodedSize() const 502{ 503 return m_decodedSize; 504} 505 506 507 508void BitmapImage::advanceAnimation(Timer<BitmapImage>*) 509{ 510 internalAdvanceAnimation(false); 511 // At this point the image region has been marked dirty, and if it's 512 // onscreen, we'll soon make a call to draw(), which will call 513 // startAnimation() again to keep the animation moving. 514} 515 516bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) 517{ 518 // Stop the animation. 519 stopAnimation(); 520 521 // See if anyone is still paying attention to this animation. If not, we don't 522 // advance and will remain suspended at the current frame until the animation is resumed. 523 if (!skippingFrames && imageObserver()->shouldPauseAnimation(this)) 524 return false; 525 526 ++m_currentFrame; 527 bool advancedAnimation = true; 528 bool destroyAll = false; 529 if (m_currentFrame >= frameCount()) { 530 ++m_repetitionsComplete; 531 532 // Get the repetition count again. If we weren't able to get a 533 // repetition count before, we should have decoded the whole image by 534 // now, so it should now be available. 535 // Note that we don't need to special-case cAnimationLoopOnce here 536 // because it is 0 (see comments on its declaration in ImageSource.h). 537 if (repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsComplete > m_repetitionCount) { 538 m_animationFinished = true; 539 m_desiredFrameStartTime = 0; 540 --m_currentFrame; 541 advancedAnimation = false; 542 } else { 543 m_currentFrame = 0; 544 destroyAll = true; 545 } 546 } 547 destroyDecodedDataIfNecessary(destroyAll); 548 549 // We need to draw this frame if we advanced to it while not skipping, or if 550 // while trying to skip frames we hit the last frame and thus had to stop. 551 if (skippingFrames != advancedAnimation) 552 imageObserver()->animationAdvanced(this); 553 return advancedAnimation; 554} 555 556bool BitmapImage::mayFillWithSolidColor() 557{ 558 if (!m_checkedForSolidColor && frameCount() > 0) { 559 checkForSolidColor(); 560 // WINCE PORT: checkForSolidColor() doesn't set m_checkedForSolidColor until 561 // it gets enough information to make final decision. 562#if !OS(WINCE) 563 ASSERT(m_checkedForSolidColor); 564#endif 565 } 566 return m_isSolidColor && !m_currentFrame; 567} 568 569Color BitmapImage::solidColor() const 570{ 571 return m_solidColor; 572} 573 574bool BitmapImage::canAnimate() 575{ 576 return shouldAnimate() && frameCount() > 1; 577} 578 579} 580