Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/BitmapImage.cpp

Issue 1962563002: Fix ImageDecoder::frameIsCompleteAtIndex - fully received instead of decoded. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: BMPDecoder + remove partial Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 size_t numFrames = frameCount(); 153 size_t numFrames = frameCount();
154 if (m_frames.size() < numFrames) 154 if (m_frames.size() < numFrames)
155 m_frames.grow(numFrames); 155 m_frames.grow(numFrames);
156 156
157 // We are caching frame snapshots. This is OK even for partially decoded fr ames, 157 // We are caching frame snapshots. This is OK even for partially decoded fr ames,
158 // as they are cleared by dataChanged() when new data arrives. 158 // as they are cleared by dataChanged() when new data arrives.
159 m_frames[index].m_frame = m_source.createFrameAtIndex(index); 159 m_frames[index].m_frame = m_source.createFrameAtIndex(index);
160 160
161 m_frames[index].m_orientation = m_source.orientationAtIndex(index); 161 m_frames[index].m_orientation = m_source.orientationAtIndex(index);
162 m_frames[index].m_haveMetadata = true; 162 m_frames[index].m_haveMetadata = true;
163 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); 163 m_frames[index].m_isFullyReceived = m_source.frameIsFullyReceivedAtIndex(ind ex);
164 if (repetitionCount(false) != cAnimationNone) 164 if (repetitionCount(false) != cAnimationNone)
165 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); 165 m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
166 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); 166 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
167 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); 167 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index);
168 168
169 notifyMemoryChanged(); 169 notifyMemoryChanged();
170 } 170 }
171 171
172 void BitmapImage::updateSize() const 172 void BitmapImage::updateSize() const
173 { 173 {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 // With ICOs, on the other hand, we may ask for arbitrary frames at 211 // With ICOs, on the other hand, we may ask for arbitrary frames at
212 // different times (e.g. because we're displaying a higher-resolution image 212 // different times (e.g. because we're displaying a higher-resolution image
213 // in the content area and using a lower-resolution one for the favicon), 213 // in the content area and using a lower-resolution one for the favicon),
214 // and the frames aren't even guaranteed to appear in the file in the same 214 // and the frames aren't even guaranteed to appear in the file in the same
215 // order as in the directory, so an arbitrary number of the frames might be 215 // order as in the directory, so an arbitrary number of the frames might be
216 // incomplete (if we ask for frames for which we've not yet reached the 216 // incomplete (if we ask for frames for which we've not yet reached the
217 // start of the frame data), and any or none of them might be the particular 217 // start of the frame data), and any or none of them might be the particular
218 // frame affected by appending new data here. Thus we have to clear all the 218 // frame affected by appending new data here. Thus we have to clear all the
219 // incomplete frames to be safe. 219 // incomplete frames to be safe.
220 for (size_t i = 0; i < m_frames.size(); ++i) { 220 for (size_t i = 0; i < m_frames.size(); ++i) {
221 // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to 221 if (m_frames[i].m_haveMetadata && !m_frames[i].m_isFullyReceived)
222 // decode any uncached (i.e. never-decoded or
223 // cleared-on-a-previous-pass) frames!
224 if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete)
225 m_frames[i].clear(true); 222 m_frames[i].clear(true);
226 } 223 }
227 224
228 // Feed all the data we've seen so far to the image decoder. 225 // Feed all the data we've seen so far to the image decoder.
229 m_allDataReceived = allDataReceived; 226 m_allDataReceived = allDataReceived;
230 ASSERT(data()); 227 ASSERT(data());
231 m_source.setData(*data(), allDataReceived); 228 m_source.setData(*data(), allDataReceived);
232 229
233 m_haveFrameCount = false; 230 m_haveFrameCount = false;
234 return isSizeAvailable(); 231 return isSizeAvailable();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 } 334 }
338 335
339 PassRefPtr<SkImage> BitmapImage::frameAtIndex(size_t index) 336 PassRefPtr<SkImage> BitmapImage::frameAtIndex(size_t index)
340 { 337 {
341 if (!ensureFrameIsCached(index)) 338 if (!ensureFrameIsCached(index))
342 return nullptr; 339 return nullptr;
343 340
344 return m_frames[index].m_frame; 341 return m_frames[index].m_frame;
345 } 342 }
346 343
347 bool BitmapImage::frameIsCompleteAtIndex(size_t index) 344 bool BitmapImage::frameIsFullyReceivedAtIndex(size_t index)
348 { 345 {
349 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in dex].m_isComplete) 346 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in dex].m_isFullyReceived)
350 return true; 347 return true;
351 348
352 return m_source.frameIsCompleteAtIndex(index); 349 return m_source.frameIsFullyReceivedAtIndex(index);
353 } 350 }
354 351
355 float BitmapImage::frameDurationAtIndex(size_t index) 352 float BitmapImage::frameDurationAtIndex(size_t index)
356 { 353 {
357 if (index < m_frames.size() && m_frames[index].m_haveMetadata) 354 if (index < m_frames.size() && m_frames[index].m_haveMetadata)
358 return m_frames[index].m_duration; 355 return m_frames[index].m_duration;
359 356
360 return m_source.frameDurationAtIndex(index); 357 return m_source.frameDurationAtIndex(index);
361 } 358 }
362 359
(...skipping 27 matching lines...) Expand all
390 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) 387 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode)
391 { 388 {
392 if (metadataMode == PreCacheMetadata) { 389 if (metadataMode == PreCacheMetadata) {
393 // frameHasAlphaAtIndex() conservatively returns false for uncached fram es. To increase the 390 // frameHasAlphaAtIndex() conservatively returns false for uncached fram es. To increase the
394 // chance of an accurate answer, pre-cache the current frame metadata. 391 // chance of an accurate answer, pre-cache the current frame metadata.
395 frameAtIndex(currentFrame()); 392 frameAtIndex(currentFrame());
396 } 393 }
397 return !frameHasAlphaAtIndex(currentFrame()); 394 return !frameHasAlphaAtIndex(currentFrame());
398 } 395 }
399 396
400 bool BitmapImage::currentFrameIsComplete() 397 bool BitmapImage::currentFrameIsFullyReceived()
401 { 398 {
402 return frameIsCompleteAtIndex(currentFrame()); 399 return frameIsFullyReceivedAtIndex(currentFrame());
403 } 400 }
404 401
405 bool BitmapImage::currentFrameIsLazyDecoded() 402 bool BitmapImage::currentFrameIsLazyDecoded()
406 { 403 {
407 RefPtr<SkImage> image = frameAtIndex(currentFrame()); 404 RefPtr<SkImage> image = frameAtIndex(currentFrame());
408 return image && image->isLazyGenerated(); 405 return image && image->isLazyGenerated();
409 } 406 }
410 407
411 ImageOrientation BitmapImage::currentFrameOrientation() 408 ImageOrientation BitmapImage::currentFrameOrientation()
412 { 409 {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 if (m_frameTimer || !shouldAnimate() || frameCount() <= 1) 447 if (m_frameTimer || !shouldAnimate() || frameCount() <= 1)
451 return; 448 return;
452 449
453 // If we aren't already animating, set now as the animation start time. 450 // If we aren't already animating, set now as the animation start time.
454 const double time = monotonicallyIncreasingTime(); 451 const double time = monotonicallyIncreasingTime();
455 if (!m_desiredFrameStartTime) 452 if (!m_desiredFrameStartTime)
456 m_desiredFrameStartTime = time; 453 m_desiredFrameStartTime = time;
457 454
458 // Don't advance the animation to an incomplete frame. 455 // Don't advance the animation to an incomplete frame.
459 size_t nextFrame = (m_currentFrame + 1) % frameCount(); 456 size_t nextFrame = (m_currentFrame + 1) % frameCount();
460 if (!m_allDataReceived && !frameIsCompleteAtIndex(nextFrame)) 457 if (!m_allDataReceived && !frameIsFullyReceivedAtIndex(nextFrame))
461 return; 458 return;
462 459
463 // Don't advance past the last frame if we haven't decoded the whole image 460 // Don't advance past the last frame if we haven't decoded the whole image
464 // yet and our repetition count is potentially unset. The repetition count 461 // yet and our repetition count is potentially unset. The repetition count
465 // in a GIF can potentially come after all the rest of the image data, so 462 // in a GIF can potentially come after all the rest of the image data, so
466 // wait on it. 463 // wait on it.
467 if (!m_allDataReceived 464 if (!m_allDataReceived
468 && (repetitionCount(false) == cAnimationLoopOnce || m_animationPolicy == ImageAnimationPolicyAnimateOnce) 465 && (repetitionCount(false) == cAnimationLoopOnce || m_animationPolicy == ImageAnimationPolicyAnimateOnce)
469 && m_currentFrame >= (frameCount() - 1)) 466 && m_currentFrame >= (frameCount() - 1))
470 return; 467 return;
(...skipping 26 matching lines...) Expand all
497 494
498 if (catchUpIfNecessary == DoNotCatchUp || time < m_desiredFrameStartTime) { 495 if (catchUpIfNecessary == DoNotCatchUp || time < m_desiredFrameStartTime) {
499 // Haven't yet reached time for next frame to start; delay until then. 496 // Haven't yet reached time for next frame to start; delay until then.
500 m_frameTimer = adoptPtr(new Timer<BitmapImage>(this, &BitmapImage::advan ceAnimation)); 497 m_frameTimer = adoptPtr(new Timer<BitmapImage>(this, &BitmapImage::advan ceAnimation));
501 m_frameTimer->startOneShot(std::max(m_desiredFrameStartTime - time, 0.), BLINK_FROM_HERE); 498 m_frameTimer->startOneShot(std::max(m_desiredFrameStartTime - time, 0.), BLINK_FROM_HERE);
502 } else { 499 } else {
503 // We've already reached or passed the time for the next frame to start. 500 // We've already reached or passed the time for the next frame to start.
504 // See if we've also passed the time for frames after that to start, in 501 // See if we've also passed the time for frames after that to start, in
505 // case we need to skip some frames entirely. Remember not to advance 502 // case we need to skip some frames entirely. Remember not to advance
506 // to an incomplete frame. 503 // to an incomplete frame.
507 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsComp leteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) { 504 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsFull yReceivedAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount( )) {
508 // Should we skip the next frame? 505 // Should we skip the next frame?
509 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDura tionAtIndex(nextFrame); 506 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDura tionAtIndex(nextFrame);
510 if (time < frameAfterNextStartTime) 507 if (time < frameAfterNextStartTime)
511 break; 508 break;
512 509
513 // Yes; skip over it without notifying our observers. 510 // Yes; skip over it without notifying our observers.
514 if (!internalAdvanceAnimation(true)) 511 if (!internalAdvanceAnimation(true))
515 return; 512 return;
516 m_desiredFrameStartTime = frameAfterNextStartTime; 513 m_desiredFrameStartTime = frameAfterNextStartTime;
517 nextFrame = frameAfterNext; 514 nextFrame = frameAfterNext;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 destroyDecodedDataIfNecessary(); 617 destroyDecodedDataIfNecessary();
621 618
622 // We need to draw this frame if we advanced to it while not skipping, or if 619 // We need to draw this frame if we advanced to it while not skipping, or if
623 // while trying to skip frames we hit the last frame and thus had to stop. 620 // while trying to skip frames we hit the last frame and thus had to stop.
624 if (skippingFrames != advancedAnimation) 621 if (skippingFrames != advancedAnimation)
625 getImageObserver()->animationAdvanced(this); 622 getImageObserver()->animationAdvanced(this);
626 return advancedAnimation; 623 return advancedAnimation;
627 } 624 }
628 625
629 } // namespace blink 626 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698