| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 BitmapImage::BitmapImage(ImageObserver* observer) | 43 BitmapImage::BitmapImage(ImageObserver* observer) |
| 44 : Image(observer) | 44 : Image(observer) |
| 45 , m_currentFrame(0) | 45 , m_currentFrame(0) |
| 46 , m_frames(0) | 46 , m_frames(0) |
| 47 , m_frameTimer(0) | 47 , m_frameTimer(0) |
| 48 , m_repetitionCount(cAnimationNone) | 48 , m_repetitionCount(cAnimationNone) |
| 49 , m_repetitionCountStatus(Unknown) | 49 , m_repetitionCountStatus(Unknown) |
| 50 , m_repetitionsComplete(0) | 50 , m_repetitionsComplete(0) |
| 51 , m_desiredFrameStartTime(0) | 51 , m_desiredFrameStartTime(0) |
| 52 , m_decodedSize(0) | |
| 53 , m_decodedPropertiesSize(0) | |
| 54 , m_frameCount(0) | 52 , m_frameCount(0) |
| 55 , m_isSolidColor(false) | 53 , m_isSolidColor(false) |
| 56 , m_checkedForSolidColor(false) | 54 , m_checkedForSolidColor(false) |
| 57 , m_animationFinished(false) | 55 , m_animationFinished(false) |
| 58 , m_allDataReceived(false) | 56 , m_allDataReceived(false) |
| 59 , m_haveSize(false) | 57 , m_haveSize(false) |
| 60 , m_sizeAvailable(false) | 58 , m_sizeAvailable(false) |
| 61 , m_hasUniformFrameSize(true) | 59 , m_hasUniformFrameSize(true) |
| 62 , m_haveFrameCount(false) | 60 , m_haveFrameCount(false) |
| 63 { | 61 { |
| 64 } | 62 } |
| 65 | 63 |
| 66 BitmapImage::BitmapImage(PassRefPtr<NativeImageSkia> nativeImage, ImageObserver*
observer) | 64 BitmapImage::BitmapImage(PassRefPtr<NativeImageSkia> nativeImage, ImageObserver*
observer) |
| 67 : Image(observer) | 65 : Image(observer) |
| 68 , m_size(nativeImage->bitmap().width(), nativeImage->bitmap().height()) | 66 , m_size(nativeImage->bitmap().width(), nativeImage->bitmap().height()) |
| 69 , m_currentFrame(0) | 67 , m_currentFrame(0) |
| 70 , m_frames(0) | 68 , m_frames(0) |
| 71 , m_frameTimer(0) | 69 , m_frameTimer(0) |
| 72 , m_repetitionCount(cAnimationNone) | 70 , m_repetitionCount(cAnimationNone) |
| 73 , m_repetitionCountStatus(Unknown) | 71 , m_repetitionCountStatus(Unknown) |
| 74 , m_repetitionsComplete(0) | 72 , m_repetitionsComplete(0) |
| 75 , m_decodedSize(nativeImage->decodedSize()) | |
| 76 , m_decodedPropertiesSize(0) | |
| 77 , m_frameCount(1) | 73 , m_frameCount(1) |
| 78 , m_isSolidColor(false) | 74 , m_isSolidColor(false) |
| 79 , m_checkedForSolidColor(false) | 75 , m_checkedForSolidColor(false) |
| 80 , m_animationFinished(true) | 76 , m_animationFinished(true) |
| 81 , m_allDataReceived(true) | 77 , m_allDataReceived(true) |
| 82 , m_haveSize(true) | 78 , m_haveSize(true) |
| 83 , m_sizeAvailable(true) | 79 , m_sizeAvailable(true) |
| 84 , m_haveFrameCount(true) | 80 , m_haveFrameCount(true) |
| 85 { | 81 { |
| 86 // Since we don't have a decoder, we can't figure out the image orientation. | 82 // Since we don't have a decoder, we can't figure out the image orientation. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 | 124 |
| 129 if (allFrameBytes > cLargeAnimationCutoff) | 125 if (allFrameBytes > cLargeAnimationCutoff) |
| 130 destroyDecodedData(false); | 126 destroyDecodedData(false); |
| 131 } | 127 } |
| 132 | 128 |
| 133 void BitmapImage::destroyMetadataAndNotify(size_t frameBytesCleared) | 129 void BitmapImage::destroyMetadataAndNotify(size_t frameBytesCleared) |
| 134 { | 130 { |
| 135 m_isSolidColor = false; | 131 m_isSolidColor = false; |
| 136 m_checkedForSolidColor = false; | 132 m_checkedForSolidColor = false; |
| 137 | 133 |
| 138 ASSERT(m_decodedSize >= frameBytesCleared); | |
| 139 m_decodedSize -= frameBytesCleared; | |
| 140 if (frameBytesCleared > 0) { | |
| 141 frameBytesCleared += m_decodedPropertiesSize; | |
| 142 m_decodedPropertiesSize = 0; | |
| 143 } | |
| 144 if (frameBytesCleared && imageObserver()) | 134 if (frameBytesCleared && imageObserver()) |
| 145 imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesClear
ed)); | 135 imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesClear
ed)); |
| 146 } | 136 } |
| 147 | 137 |
| 148 void BitmapImage::cacheFrame(size_t index) | 138 void BitmapImage::cacheFrame(size_t index) |
| 149 { | 139 { |
| 150 size_t numFrames = frameCount(); | 140 size_t numFrames = frameCount(); |
| 151 if (m_frames.size() < numFrames) | 141 if (m_frames.size() < numFrames) |
| 152 m_frames.grow(numFrames); | 142 m_frames.grow(numFrames); |
| 153 | 143 |
| 154 m_frames[index].m_frame = m_source.createFrameAtIndex(index); | 144 m_frames[index].m_frame = m_source.createFrameAtIndex(index); |
| 155 if (numFrames == 1 && m_frames[index].m_frame) | 145 if (numFrames == 1 && m_frames[index].m_frame) |
| 156 checkForSolidColor(); | 146 checkForSolidColor(); |
| 157 | 147 |
| 158 m_frames[index].m_orientation = m_source.orientationAtIndex(index); | 148 m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
| 159 m_frames[index].m_haveMetadata = true; | 149 m_frames[index].m_haveMetadata = true; |
| 160 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); | 150 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); |
| 161 if (repetitionCount(false) != cAnimationNone) | 151 if (repetitionCount(false) != cAnimationNone) |
| 162 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); | 152 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); |
| 163 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); | 153 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| 164 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); | 154 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); |
| 165 | 155 |
| 166 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); | 156 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); |
| 167 if (frameSize != m_size) | 157 if (frameSize != m_size) |
| 168 m_hasUniformFrameSize = false; | 158 m_hasUniformFrameSize = false; |
| 169 if (m_frames[index].m_frame) { | 159 if (m_frames[index].m_frame) { |
| 170 int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes); | 160 int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes); |
| 171 m_decodedSize += deltaBytes; | |
| 172 // The fully-decoded frame will subsume the partially decoded data used | 161 // The fully-decoded frame will subsume the partially decoded data used |
| 173 // to determine image properties. | 162 // to determine image properties. |
| 174 deltaBytes -= m_decodedPropertiesSize; | |
| 175 m_decodedPropertiesSize = 0; | |
| 176 if (imageObserver()) | 163 if (imageObserver()) |
| 177 imageObserver()->decodedSizeChanged(this, deltaBytes); | 164 imageObserver()->decodedSizeChanged(this, deltaBytes); |
| 178 } | 165 } |
| 179 } | 166 } |
| 180 | 167 |
| 181 void BitmapImage::didDecodeProperties() const | |
| 182 { | |
| 183 if (m_decodedSize) | |
| 184 return; | |
| 185 size_t updatedSize = m_source.bytesDecodedToDetermineProperties(); | |
| 186 if (m_decodedPropertiesSize == updatedSize) | |
| 187 return; | |
| 188 int deltaBytes = updatedSize - m_decodedPropertiesSize; | |
| 189 #if !ASSERT_DISABLED | |
| 190 bool overflow = updatedSize > m_decodedPropertiesSize && deltaBytes < 0; | |
| 191 bool underflow = updatedSize < m_decodedPropertiesSize && deltaBytes > 0; | |
| 192 ASSERT(!overflow && !underflow); | |
| 193 #endif | |
| 194 m_decodedPropertiesSize = updatedSize; | |
| 195 if (imageObserver()) | |
| 196 imageObserver()->decodedSizeChanged(this, deltaBytes); | |
| 197 } | |
| 198 | |
| 199 void BitmapImage::updateSize() const | 168 void BitmapImage::updateSize() const |
| 200 { | 169 { |
| 201 if (!m_sizeAvailable || m_haveSize) | 170 if (!m_sizeAvailable || m_haveSize) |
| 202 return; | 171 return; |
| 203 | 172 |
| 204 m_size = m_source.size(); | 173 m_size = m_source.size(); |
| 205 m_sizeRespectingOrientation = m_source.size(RespectImageOrientation); | 174 m_sizeRespectingOrientation = m_source.size(RespectImageOrientation); |
| 206 m_haveSize = true; | 175 m_haveSize = true; |
| 207 didDecodeProperties(); | |
| 208 } | 176 } |
| 209 | 177 |
| 210 IntSize BitmapImage::size() const | 178 IntSize BitmapImage::size() const |
| 211 { | 179 { |
| 212 updateSize(); | 180 updateSize(); |
| 213 return m_size; | 181 return m_size; |
| 214 } | 182 } |
| 215 | 183 |
| 216 IntSize BitmapImage::sizeRespectingOrientation() const | 184 IntSize BitmapImage::sizeRespectingOrientation() const |
| 217 { | 185 { |
| 218 updateSize(); | 186 updateSize(); |
| 219 return m_sizeRespectingOrientation; | 187 return m_sizeRespectingOrientation; |
| 220 } | 188 } |
| 221 | 189 |
| 222 IntSize BitmapImage::currentFrameSize() const | 190 IntSize BitmapImage::currentFrameSize() const |
| 223 { | 191 { |
| 224 if (!m_currentFrame || m_hasUniformFrameSize) | 192 if (!m_currentFrame || m_hasUniformFrameSize) |
| 225 return size(); | 193 return size(); |
| 226 IntSize frameSize = m_source.frameSizeAtIndex(m_currentFrame); | 194 IntSize frameSize = m_source.frameSizeAtIndex(m_currentFrame); |
| 227 didDecodeProperties(); | |
| 228 return frameSize; | 195 return frameSize; |
| 229 } | 196 } |
| 230 | 197 |
| 231 bool BitmapImage::getHotSpot(IntPoint& hotSpot) const | 198 bool BitmapImage::getHotSpot(IntPoint& hotSpot) const |
| 232 { | 199 { |
| 233 bool result = m_source.getHotSpot(hotSpot); | 200 bool result = m_source.getHotSpot(hotSpot); |
| 234 didDecodeProperties(); | |
| 235 return result; | 201 return result; |
| 236 } | 202 } |
| 237 | 203 |
| 238 bool BitmapImage::dataChanged(bool allDataReceived) | 204 bool BitmapImage::dataChanged(bool allDataReceived) |
| 239 { | 205 { |
| 240 // Clear all partially-decoded frames. For most image formats, there is only | 206 // Clear all partially-decoded frames. For most image formats, there is only |
| 241 // one frame, but at least GIF and ICO can have more. With GIFs, the frames | 207 // one frame, but at least GIF and ICO can have more. With GIFs, the frames |
| 242 // come in order and we ask to decode them in order, waiting to request a | 208 // come in order and we ask to decode them in order, waiting to request a |
| 243 // subsequent frame until the prior one is complete. Given that we clear | 209 // subsequent frame until the prior one is complete. Given that we clear |
| 244 // incomplete frames here, this means there is at most one incomplete frame | 210 // incomplete frames here, this means there is at most one incomplete frame |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 if (ImageObserver* observer = imageObserver()) | 294 if (ImageObserver* observer = imageObserver()) |
| 329 observer->didDraw(this); | 295 observer->didDraw(this); |
| 330 } | 296 } |
| 331 | 297 |
| 332 size_t BitmapImage::frameCount() | 298 size_t BitmapImage::frameCount() |
| 333 { | 299 { |
| 334 if (!m_haveFrameCount) { | 300 if (!m_haveFrameCount) { |
| 335 m_frameCount = m_source.frameCount(); | 301 m_frameCount = m_source.frameCount(); |
| 336 // If decoder is not initialized yet, m_source.frameCount() returns 0. | 302 // If decoder is not initialized yet, m_source.frameCount() returns 0. |
| 337 if (m_frameCount) { | 303 if (m_frameCount) { |
| 338 didDecodeProperties(); | |
| 339 m_haveFrameCount = true; | 304 m_haveFrameCount = true; |
| 340 } | 305 } |
| 341 } | 306 } |
| 342 return m_frameCount; | 307 return m_frameCount; |
| 343 } | 308 } |
| 344 | 309 |
| 345 bool BitmapImage::isSizeAvailable() | 310 bool BitmapImage::isSizeAvailable() |
| 346 { | 311 { |
| 347 if (m_sizeAvailable) | 312 if (m_sizeAvailable) |
| 348 return true; | 313 return true; |
| 349 | 314 |
| 350 m_sizeAvailable = m_source.isSizeAvailable(); | 315 m_sizeAvailable = m_source.isSizeAvailable(); |
| 351 didDecodeProperties(); | |
| 352 | 316 |
| 353 return m_sizeAvailable; | 317 return m_sizeAvailable; |
| 354 } | 318 } |
| 355 | 319 |
| 356 bool BitmapImage::ensureFrameIsCached(size_t index) | 320 bool BitmapImage::ensureFrameIsCached(size_t index) |
| 357 { | 321 { |
| 358 if (index >= frameCount()) | 322 if (index >= frameCount()) |
| 359 return false; | 323 return false; |
| 360 | 324 |
| 361 if (index >= m_frames.size() || !m_frames[index].m_frame) | 325 if (index >= m_frames.size() || !m_frames[index].m_frame) |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 | 395 |
| 432 | 396 |
| 433 int BitmapImage::repetitionCount(bool imageKnownToBeComplete) | 397 int BitmapImage::repetitionCount(bool imageKnownToBeComplete) |
| 434 { | 398 { |
| 435 if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Unc
ertain) && imageKnownToBeComplete)) { | 399 if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Unc
ertain) && imageKnownToBeComplete)) { |
| 436 // Snag the repetition count. If |imageKnownToBeComplete| is false, the | 400 // Snag the repetition count. If |imageKnownToBeComplete| is false, the |
| 437 // repetition count may not be accurate yet for GIFs; in this case the | 401 // repetition count may not be accurate yet for GIFs; in this case the |
| 438 // decoder will default to cAnimationLoopOnce, and we'll try and read | 402 // decoder will default to cAnimationLoopOnce, and we'll try and read |
| 439 // the count again once the whole image is decoded. | 403 // the count again once the whole image is decoded. |
| 440 m_repetitionCount = m_source.repetitionCount(); | 404 m_repetitionCount = m_source.repetitionCount(); |
| 441 didDecodeProperties(); | |
| 442 m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount =
= cAnimationNone) ? Certain : Uncertain; | 405 m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount =
= cAnimationNone) ? Certain : Uncertain; |
| 443 } | 406 } |
| 444 return m_repetitionCount; | 407 return m_repetitionCount; |
| 445 } | 408 } |
| 446 | 409 |
| 447 bool BitmapImage::shouldAnimate() | 410 bool BitmapImage::shouldAnimate() |
| 448 { | 411 { |
| 449 return (repetitionCount(false) != cAnimationNone && !m_animationFinished &&
imageObserver()); | 412 return (repetitionCount(false) != cAnimationNone && !m_animationFinished &&
imageObserver()); |
| 450 } | 413 } |
| 451 | 414 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 stopAnimation(); | 521 stopAnimation(); |
| 559 m_currentFrame = 0; | 522 m_currentFrame = 0; |
| 560 m_repetitionsComplete = 0; | 523 m_repetitionsComplete = 0; |
| 561 m_desiredFrameStartTime = 0; | 524 m_desiredFrameStartTime = 0; |
| 562 m_animationFinished = false; | 525 m_animationFinished = false; |
| 563 | 526 |
| 564 // For extremely large animations, when the animation is reset, we just thro
w everything away. | 527 // For extremely large animations, when the animation is reset, we just thro
w everything away. |
| 565 destroyDecodedDataIfNecessary(); | 528 destroyDecodedDataIfNecessary(); |
| 566 } | 529 } |
| 567 | 530 |
| 568 unsigned BitmapImage::decodedSize() const | |
| 569 { | |
| 570 return m_decodedSize; | |
| 571 } | |
| 572 | |
| 573 | |
| 574 | |
| 575 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) | 531 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) |
| 576 { | 532 { |
| 577 internalAdvanceAnimation(false); | 533 internalAdvanceAnimation(false); |
| 578 // At this point the image region has been marked dirty, and if it's | 534 // At this point the image region has been marked dirty, and if it's |
| 579 // onscreen, we'll soon make a call to draw(), which will call | 535 // onscreen, we'll soon make a call to draw(), which will call |
| 580 // startAnimation() again to keep the animation moving. | 536 // startAnimation() again to keep the animation moving. |
| 581 } | 537 } |
| 582 | 538 |
| 583 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) | 539 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) |
| 584 { | 540 { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 } | 601 } |
| 646 return m_isSolidColor && !m_currentFrame; | 602 return m_isSolidColor && !m_currentFrame; |
| 647 } | 603 } |
| 648 | 604 |
| 649 Color BitmapImage::solidColor() const | 605 Color BitmapImage::solidColor() const |
| 650 { | 606 { |
| 651 return m_solidColor; | 607 return m_solidColor; |
| 652 } | 608 } |
| 653 | 609 |
| 654 } | 610 } |
| OLD | NEW |