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