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 TRACE_EVENT0("webkit", "BitmapImage::dataChanged"); | 206 TRACE_EVENT0("webkit", "BitmapImage::dataChanged"); |
241 | 207 |
242 // Clear all partially-decoded frames. For most image formats, there is only | 208 // Clear all partially-decoded frames. For most image formats, there is only |
243 // one frame, but at least GIF and ICO can have more. With GIFs, the frames | 209 // one frame, but at least GIF and ICO can have more. With GIFs, the frames |
244 // come in order and we ask to decode them in order, waiting to request a | 210 // come in order and we ask to decode them in order, waiting to request a |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 if (ImageObserver* observer = imageObserver()) | 296 if (ImageObserver* observer = imageObserver()) |
331 observer->didDraw(this); | 297 observer->didDraw(this); |
332 } | 298 } |
333 | 299 |
334 size_t BitmapImage::frameCount() | 300 size_t BitmapImage::frameCount() |
335 { | 301 { |
336 if (!m_haveFrameCount) { | 302 if (!m_haveFrameCount) { |
337 m_frameCount = m_source.frameCount(); | 303 m_frameCount = m_source.frameCount(); |
338 // If decoder is not initialized yet, m_source.frameCount() returns 0. | 304 // If decoder is not initialized yet, m_source.frameCount() returns 0. |
339 if (m_frameCount) { | 305 if (m_frameCount) { |
340 didDecodeProperties(); | |
341 m_haveFrameCount = true; | 306 m_haveFrameCount = true; |
342 } | 307 } |
343 } | 308 } |
344 return m_frameCount; | 309 return m_frameCount; |
345 } | 310 } |
346 | 311 |
347 bool BitmapImage::isSizeAvailable() | 312 bool BitmapImage::isSizeAvailable() |
348 { | 313 { |
349 if (m_sizeAvailable) | 314 if (m_sizeAvailable) |
350 return true; | 315 return true; |
351 | 316 |
352 m_sizeAvailable = m_source.isSizeAvailable(); | 317 m_sizeAvailable = m_source.isSizeAvailable(); |
353 didDecodeProperties(); | |
354 | 318 |
355 return m_sizeAvailable; | 319 return m_sizeAvailable; |
356 } | 320 } |
357 | 321 |
358 bool BitmapImage::ensureFrameIsCached(size_t index) | 322 bool BitmapImage::ensureFrameIsCached(size_t index) |
359 { | 323 { |
360 if (index >= frameCount()) | 324 if (index >= frameCount()) |
361 return false; | 325 return false; |
362 | 326 |
363 if (index >= m_frames.size() || !m_frames[index].m_frame) | 327 if (index >= m_frames.size() || !m_frames[index].m_frame) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 | 397 |
434 | 398 |
435 int BitmapImage::repetitionCount(bool imageKnownToBeComplete) | 399 int BitmapImage::repetitionCount(bool imageKnownToBeComplete) |
436 { | 400 { |
437 if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Unc
ertain) && imageKnownToBeComplete)) { | 401 if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Unc
ertain) && imageKnownToBeComplete)) { |
438 // Snag the repetition count. If |imageKnownToBeComplete| is false, the | 402 // Snag the repetition count. If |imageKnownToBeComplete| is false, the |
439 // repetition count may not be accurate yet for GIFs; in this case the | 403 // repetition count may not be accurate yet for GIFs; in this case the |
440 // decoder will default to cAnimationLoopOnce, and we'll try and read | 404 // decoder will default to cAnimationLoopOnce, and we'll try and read |
441 // the count again once the whole image is decoded. | 405 // the count again once the whole image is decoded. |
442 m_repetitionCount = m_source.repetitionCount(); | 406 m_repetitionCount = m_source.repetitionCount(); |
443 didDecodeProperties(); | |
444 m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount =
= cAnimationNone) ? Certain : Uncertain; | 407 m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount =
= cAnimationNone) ? Certain : Uncertain; |
445 } | 408 } |
446 return m_repetitionCount; | 409 return m_repetitionCount; |
447 } | 410 } |
448 | 411 |
449 bool BitmapImage::shouldAnimate() | 412 bool BitmapImage::shouldAnimate() |
450 { | 413 { |
451 return (repetitionCount(false) != cAnimationNone && !m_animationFinished &&
imageObserver()); | 414 return (repetitionCount(false) != cAnimationNone && !m_animationFinished &&
imageObserver()); |
452 } | 415 } |
453 | 416 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 stopAnimation(); | 523 stopAnimation(); |
561 m_currentFrame = 0; | 524 m_currentFrame = 0; |
562 m_repetitionsComplete = 0; | 525 m_repetitionsComplete = 0; |
563 m_desiredFrameStartTime = 0; | 526 m_desiredFrameStartTime = 0; |
564 m_animationFinished = false; | 527 m_animationFinished = false; |
565 | 528 |
566 // For extremely large animations, when the animation is reset, we just thro
w everything away. | 529 // For extremely large animations, when the animation is reset, we just thro
w everything away. |
567 destroyDecodedDataIfNecessary(); | 530 destroyDecodedDataIfNecessary(); |
568 } | 531 } |
569 | 532 |
570 unsigned BitmapImage::decodedSize() const | |
571 { | |
572 return m_decodedSize; | |
573 } | |
574 | |
575 | |
576 | |
577 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) | 533 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) |
578 { | 534 { |
579 internalAdvanceAnimation(false); | 535 internalAdvanceAnimation(false); |
580 // At this point the image region has been marked dirty, and if it's | 536 // At this point the image region has been marked dirty, and if it's |
581 // onscreen, we'll soon make a call to draw(), which will call | 537 // onscreen, we'll soon make a call to draw(), which will call |
582 // startAnimation() again to keep the animation moving. | 538 // startAnimation() again to keep the animation moving. |
583 } | 539 } |
584 | 540 |
585 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) | 541 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) |
586 { | 542 { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 } | 603 } |
648 return m_isSolidColor && !m_currentFrame; | 604 return m_isSolidColor && !m_currentFrame; |
649 } | 605 } |
650 | 606 |
651 Color BitmapImage::solidColor() const | 607 Color BitmapImage::solidColor() const |
652 { | 608 { |
653 return m_solidColor; | 609 return m_solidColor; |
654 } | 610 } |
655 | 611 |
656 } | 612 } |
OLD | NEW |