OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include "platform/image-decoders/gif/GIFImageReader.h" | 28 #include "platform/image-decoders/gif/GIFImageReader.h" |
29 #include "wtf/NotFound.h" | 29 #include "wtf/NotFound.h" |
30 #include "wtf/PtrUtil.h" | 30 #include "wtf/PtrUtil.h" |
31 #include <limits> | 31 #include <limits> |
32 | 32 |
33 namespace blink { | 33 namespace blink { |
34 | 34 |
35 GIFImageDecoder::GIFImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOp
tion colorOptions, size_t maxDecodedBytes) | 35 GIFImageDecoder::GIFImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOp
tion colorOptions, size_t maxDecodedBytes) |
36 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes) | 36 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes) |
37 , m_purgeAggressively(false) | |
38 , m_repetitionCount(cAnimationLoopOnce) | 37 , m_repetitionCount(cAnimationLoopOnce) |
39 { | 38 { |
40 } | 39 } |
41 | 40 |
42 GIFImageDecoder::~GIFImageDecoder() | 41 GIFImageDecoder::~GIFImageDecoder() |
43 { | 42 { |
44 } | 43 } |
45 | 44 |
46 void GIFImageDecoder::onSetData(SegmentReader* data) | 45 void GIFImageDecoder::onSetData(SegmentReader* data) |
47 { | 46 { |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 } | 374 } |
376 } | 375 } |
377 | 376 |
378 // Update our status to be partially complete. | 377 // Update our status to be partially complete. |
379 buffer->setStatus(ImageFrame::FramePartial); | 378 buffer->setStatus(ImageFrame::FramePartial); |
380 | 379 |
381 // Reset the alpha pixel tracker for this frame. | 380 // Reset the alpha pixel tracker for this frame. |
382 m_currentBufferSawAlpha = false; | 381 m_currentBufferSawAlpha = false; |
383 return true; | 382 return true; |
384 } | 383 } |
385 | |
386 void GIFImageDecoder::updateAggressivePurging(size_t index) | |
387 { | |
388 if (m_purgeAggressively) | |
389 return; | |
390 | |
391 // We don't want to cache so much that we cause a memory issue. | |
392 // | |
393 // If we used a LRU cache we would fill it and then on next animation loop | |
394 // we would need to decode all the frames again -- the LRU would give no | |
395 // benefit and would consume more memory. | |
396 // So instead, simply purge unused frames if caching all of the frames of | |
397 // the image would use more memory than the image decoder is allowed | |
398 // (m_maxDecodedBytes) or would overflow 32 bits.. | |
399 // | |
400 // As we decode we will learn the total number of frames, and thus total | |
401 // possible image memory used. | |
402 | |
403 const uint64_t frameArea = decodedSize().area(); | |
404 // We are about to multiply by 4, which may require an extra bit of storage | |
405 bool wouldOverflow = frameArea > (UINT64_C(1) << 62); | |
406 if (wouldOverflow) { | |
407 m_purgeAggressively = true; | |
408 return; | |
409 } | |
410 | |
411 const uint64_t frameMemoryUsage = frameArea * 4; // 4 bytes per pixel | |
412 // We are about to multiply by a size_t, which does not have a fixed | |
413 // size. | |
414 // To simplify things, let's make sure our per-frame memory usage and | |
415 // index can be stored in 32 bits and store the multiplicand in a 64-bit | |
416 // number. | |
417 wouldOverflow = (frameMemoryUsage > (UINT32_C(1) << 31)) | |
418 || (index > (UINT32_C(1) << 31)); | |
419 if (wouldOverflow) { | |
420 m_purgeAggressively = true; | |
421 return; | |
422 } | |
423 | |
424 const uint64_t totalMemoryUsage = frameMemoryUsage * index; | |
425 if (totalMemoryUsage > m_maxDecodedBytes) { | |
426 m_purgeAggressively = true; | |
427 } | |
428 } | |
429 } // namespace blink | 384 } // namespace blink |
OLD | NEW |