1 /* 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig (at) 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 "PlatformString.h" 35 #include "Timer.h" 36 #include <wtf/CurrentTime.h> 37 #include <wtf/Vector.h> 38 39 namespace WebCore { 40 41 static int frameBytes(const IntSize& frameSize) 42 { 43 return frameSize.width() * frameSize.height() * 4; 44 } 45 46 BitmapImage::BitmapImage(ImageObserver* observer) 47 : Image(observer) 48 , m_currentFrame(0) 49 , m_frames(0) 50 , m_frameTimer(0) 51 , m_repetitionCount(cAnimationNone) 52 , m_repetitionCountStatus(Unknown) 53 , m_repetitionsComplete(0) 54 , m_desiredFrameStartTime(0) 55 , m_isSolidColor(false) 56 , m_checkedForSolidColor(false) 57 , m_animationFinished(false) 58 , m_allDataReceived(false) 59 , m_haveSize(false) 60 , m_sizeAvailable(false) 61 , m_hasUniformFrameSize(true) 62 , m_decodedSize(0) 63 , m_haveFrameCount(false) 64 , m_frameCount(0) 65 { 66 initPlatformData(); 67 } 68 69 BitmapImage::~BitmapImage() 70 { 71 invalidatePlatformData(); 72 stopAnimation(); 73 } 74 75 void BitmapImage::destroyDecodedData(bool destroyAll) 76 { 77 int framesCleared = 0; 78 const size_t clearBeforeFrame = destroyAll ? m_frames.size() : m_currentFrame; 79 for (size_t i = 0; i < clearBeforeFrame; ++i) { 80 // The underlying frame isn't actually changing (we're just trying to 81 // save the memory for the framebuffer data), so we don't need to clear 82 // the metadata. 83 if (m_frames[i].clear(false)) 84 ++framesCleared; 85 } 86 87 destroyMetadataAndNotify(framesCleared); 88 89 m_source.clear(destroyAll, clearBeforeFrame, data(), m_allDataReceived); 90 return; 91 } 92 93 void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll) 94 { 95 // Animated images >5MB are considered large enough that we'll only hang on 96 // to one frame at a time. 97 static const unsigned cLargeAnimationCutoff = 5242880; 98 if (m_frames.size() * frameBytes(m_size) > cLargeAnimationCutoff) 99 destroyDecodedData(destroyAll); 100 } 101 102 void BitmapImage::destroyMetadataAndNotify(int framesCleared) 103 { 104 m_isSolidColor = false; 105 invalidatePlatformData(); 106 107 const int deltaBytes = framesCleared * -frameBytes(m_size); 108 m_decodedSize += deltaBytes; 109 if (deltaBytes && imageObserver()) 110 imageObserver()->decodedSizeChanged(this, deltaBytes); 111 } 112 113 void BitmapImage::cacheFrame(size_t index) 114 { 115 size_t numFrames = frameCount(); 116 ASSERT(m_decodedSize == 0 || numFrames > 1); 117 118 if (m_frames.size() < numFrames) 119 m_frames.grow(numFrames); 120 121 m_frames[index].m_frame = m_source.createFrameAtIndex(index); 122 if (numFrames == 1 && m_frames[index].m_frame) 123 checkForSolidColor(); 124 125 m_frames[index].m_haveMetadata = true; 126 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); 127 if (repetitionCount(false) != cAnimationNone) 128 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); 129 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); 130 131 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); 132 if (frameSize != m_size) 133 m_hasUniformFrameSize = false; 134 if (m_frames[index].m_frame) { 135 const int deltaBytes = frameBytes(frameSize); 136 m_decodedSize += deltaBytes; 137 if (imageObserver()) 138 imageObserver()->decodedSizeChanged(this, deltaBytes); 139 } 140 } 141 142 IntSize BitmapImage::size() const 143 { 144 if (m_sizeAvailable && !m_haveSize) { 145 m_size = m_source.size(); 146 m_haveSize = true; 147 } 148 return m_size; 149 } 150 151 IntSize BitmapImage::currentFrameSize() const 152 { 153 if (!m_currentFrame || m_hasUniformFrameSize) 154 return size(); 155 return m_source.frameSizeAtIndex(m_currentFrame); 156 } 157 158 bool BitmapImage::dataChanged(bool allDataReceived) 159 { 160 // Because we're modifying the current frame, clear its (now possibly 161 // inaccurate) metadata as well. 162 destroyMetadataAndNotify((!m_frames.isEmpty() && m_frames[m_frames.size() - 1].clear(true)) ? 1 : 0); 163 164 // Feed all the data we've seen so far to the image decoder. 165 m_allDataReceived = allDataReceived; 166 m_source.setData(data(), allDataReceived); 167 168 // Clear the frame count. 169 m_haveFrameCount = false; 170 171 m_hasUniformFrameSize = true; 172 173 // Image properties will not be available until the first frame of the file 174 // reaches kCGImageStatusIncomplete. 175 return isSizeAvailable(); 176 } 177 178 String BitmapImage::filenameExtension() const 179 { 180 return m_source.filenameExtension(); 181 } 182 183 size_t BitmapImage::frameCount() 184 { 185 if (!m_haveFrameCount) { 186 m_haveFrameCount = true; 187 m_frameCount = m_source.frameCount(); 188 } 189 return m_frameCount; 190 } 191 192 bool BitmapImage::isSizeAvailable() 193 { 194 if (m_sizeAvailable) 195 return true; 196 197 m_sizeAvailable = m_source.isSizeAvailable(); 198 199 return m_sizeAvailable; 200 } 201 202 NativeImagePtr BitmapImage::frameAtIndex(size_t index) 203 { 204 if (index >= frameCount()) 205 return 0; 206 207 if (index >= m_frames.size() || !m_frames[index].m_frame) 208 cacheFrame(index); 209 210 return m_frames[index].m_frame; 211 } 212 213 bool BitmapImage::frameIsCompleteAtIndex(size_t index) 214 { 215 if (index >= frameCount()) 216 return true; 217 218 if (index >= m_frames.size() || !m_frames[index].m_haveMetadata) 219 cacheFrame(index); 220 221 return m_frames[index].m_isComplete; 222 } 223 224 float BitmapImage::frameDurationAtIndex(size_t index) 225 { 226 if (index >= frameCount()) 227 return 0; 228 229 if (index >= m_frames.size() || !m_frames[index].m_haveMetadata) 230 cacheFrame(index); 231 232 return m_frames[index].m_duration; 233 } 234 235 bool BitmapImage::frameHasAlphaAtIndex(size_t index) 236 { 237 if (index >= frameCount()) 238 return true; 239 240 if (index >= m_frames.size() || !m_frames[index].m_haveMetadata) 241 cacheFrame(index); 242 243 return m_frames[index].m_hasAlpha; 244 } 245 246 int BitmapImage::repetitionCount(bool imageKnownToBeComplete) 247 { 248 if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Uncertain) && imageKnownToBeComplete)) { 249 // Snag the repetition count. If |imageKnownToBeComplete| is false, the 250 // repetition count may not be accurate yet for GIFs; in this case the 251 // decoder will default to cAnimationLoopOnce, and we'll try and read 252 // the count again once the whole image is decoded. 253 m_repetitionCount = m_source.repetitionCount(); 254 m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == cAnimationNone) ? Certain : Uncertain; 255 } 256 return m_repetitionCount; 257 } 258 259 bool BitmapImage::shouldAnimate() 260 { 261 return (repetitionCount(false) != cAnimationNone && !m_animationFinished && imageObserver()); 262 } 263 264 void BitmapImage::startAnimation(bool catchUpIfNecessary) 265 { 266 #ifdef ANDROID_ANIMATED_GIF 267 // We can't ever seem to keep up, so always let us just show the next frame 268 catchUpIfNecessary = false; 269 #endif 270 if (m_frameTimer || !shouldAnimate() || frameCount() <= 1) 271 return; 272 273 // Determine time for next frame to start. By ignoring paint and timer lag 274 // in this calculation, we make the animation appear to run at its desired 275 // rate regardless of how fast it's being repainted. 276 const double currentDuration = frameDurationAtIndex(m_currentFrame); 277 const double time = currentTime(); 278 if (m_desiredFrameStartTime == 0) { 279 m_desiredFrameStartTime = time + currentDuration; 280 } else { 281 m_desiredFrameStartTime += currentDuration; 282 283 // When an animated image is more than five minutes out of date, the 284 // user probably doesn't care about resyncing and we could burn a lot of 285 // time looping through frames below. Just reset the timings. 286 const double cAnimationResyncCutoff = 5 * 60; 287 if ((time - m_desiredFrameStartTime) > cAnimationResyncCutoff) 288 m_desiredFrameStartTime = time + currentDuration; 289 } 290 291 // Don't advance the animation to an incomplete frame. 292 size_t nextFrame = (m_currentFrame + 1) % frameCount(); 293 if (!m_allDataReceived && !frameIsCompleteAtIndex(nextFrame)) 294 return; 295 296 // Don't advance past the last frame if we haven't decoded the whole image 297 // yet and our repetition count is potentially unset. The repetition count 298 // in a GIF can potentially come after all the rest of the image data, so 299 // wait on it. 300 if (!m_allDataReceived && repetitionCount(false) == cAnimationLoopOnce && m_currentFrame >= (frameCount() - 1)) 301 return; 302 303 // The image may load more slowly than it's supposed to animate, so that by 304 // the time we reach the end of the first repetition, we're well behind. 305 // Clamp the desired frame start time in this case, so that we don't skip 306 // frames (or whole iterations) trying to "catch up". This is a tradeoff: 307 // It guarantees users see the whole animation the second time through and 308 // don't miss any repetitions, and is closer to what other browsers do; on 309 // the other hand, it makes animations "less accurate" for pages that try to 310 // sync an image and some other resource (e.g. audio), especially if users 311 // switch tabs (and thus stop drawing the animation, which will pause it) 312 // during that initial loop, then switch back later. 313 if (nextFrame == 0 && m_repetitionsComplete == 0 && m_desiredFrameStartTime < time) 314 m_desiredFrameStartTime = time; 315 316 if (!catchUpIfNecessary || time < m_desiredFrameStartTime) { 317 // Haven't yet reached time for next frame to start; delay until then. 318 m_frameTimer = new Timer<BitmapImage>(this, &BitmapImage::advanceAnimation); 319 m_frameTimer->startOneShot(std::max(m_desiredFrameStartTime - time, 0.)); 320 } else { 321 // We've already reached or passed the time for the next frame to start. 322 // See if we've also passed the time for frames after that to start, in 323 // case we need to skip some frames entirely. Remember not to advance 324 // to an incomplete frame. 325 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsCompleteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) { 326 // Should we skip the next frame? 327 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDurationAtIndex(nextFrame); 328 if (time < frameAfterNextStartTime) 329 break; 330 331 // Yes; skip over it without notifying our observers. 332 if (!internalAdvanceAnimation(true)) 333 return; 334 m_desiredFrameStartTime = frameAfterNextStartTime; 335 nextFrame = frameAfterNext; 336 } 337 338 // Draw the next frame immediately. Note that m_desiredFrameStartTime 339 // may be in the past, meaning the next time through this function we'll 340 // kick off the next advancement sooner than this frame's duration would 341 // suggest. 342 if (internalAdvanceAnimation(false)) { 343 // The image region has been marked dirty, but once we return to our 344 // caller, draw() will clear it, and nothing will cause the 345 // animation to advance again. We need to start the timer for the 346 // next frame running, or the animation can hang. (Compare this 347 // with when advanceAnimation() is called, and the region is dirtied 348 // while draw() is not in the callstack, meaning draw() gets called 349 // to update the region and thus startAnimation() is reached again.) 350 // NOTE: For large images with slow or heavily-loaded systems, 351 // throwing away data as we go (see destroyDecodedData()) means we 352 // can spend so much time re-decoding data above that by the time we 353 // reach here we're behind again. If we let startAnimation() run 354 // the catch-up code again, we can get long delays without painting 355 // as we race the timer, or even infinite recursion. In this 356 // situation the best we can do is to simply change frames as fast 357 // as possible, so force startAnimation() to set a zero-delay timer 358 // and bail out if we're not caught up. 359 startAnimation(false); 360 } 361 } 362 } 363 364 void BitmapImage::stopAnimation() 365 { 366 // This timer is used to animate all occurrences of this image. Don't invalidate 367 // the timer unless all renderers have stopped drawing. 368 delete m_frameTimer; 369 m_frameTimer = 0; 370 } 371 372 void BitmapImage::resetAnimation() 373 { 374 stopAnimation(); 375 m_currentFrame = 0; 376 m_repetitionsComplete = 0; 377 m_desiredFrameStartTime = 0; 378 m_animationFinished = false; 379 380 // For extremely large animations, when the animation is reset, we just throw everything away. 381 destroyDecodedDataIfNecessary(true); 382 } 383 384 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) 385 { 386 internalAdvanceAnimation(false); 387 // At this point the image region has been marked dirty, and if it's 388 // onscreen, we'll soon make a call to draw(), which will call 389 // startAnimation() again to keep the animation moving. 390 } 391 392 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) 393 { 394 // Stop the animation. 395 stopAnimation(); 396 397 // See if anyone is still paying attention to this animation. If not, we don't 398 // advance and will remain suspended at the current frame until the animation is resumed. 399 if (!skippingFrames && imageObserver()->shouldPauseAnimation(this)) 400 return false; 401 402 ++m_currentFrame; 403 bool advancedAnimation = true; 404 bool destroyAll = false; 405 if (m_currentFrame >= frameCount()) { 406 ++m_repetitionsComplete; 407 408 // Get the repetition count again. If we weren't able to get a 409 // repetition count before, we should have decoded the whole image by 410 // now, so it should now be available. 411 if (repetitionCount(true) && m_repetitionsComplete >= m_repetitionCount) { 412 m_animationFinished = true; 413 m_desiredFrameStartTime = 0; 414 --m_currentFrame; 415 advancedAnimation = false; 416 } else { 417 m_currentFrame = 0; 418 destroyAll = true; 419 } 420 } 421 destroyDecodedDataIfNecessary(destroyAll); 422 423 // We need to draw this frame if we advanced to it while not skipping, or if 424 // while trying to skip frames we hit the last frame and thus had to stop. 425 if (skippingFrames != advancedAnimation) 426 imageObserver()->animationAdvanced(this); 427 return advancedAnimation; 428 } 429 430 } 431