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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgc
olor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevBuff
er->originalFrameRect())) | 213 if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgc
olor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevBuff
er->originalFrameRect())) |
214 buffer.setHasAlpha(false); | 214 buffer.setHasAlpha(false); |
215 } | 215 } |
216 } | 216 } |
217 | 217 |
218 return true; | 218 return true; |
219 } | 219 } |
220 | 220 |
221 size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) | 221 size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) |
222 { | 222 { |
223 // We need to preserve frames such that: | 223 // We expect that after this call, we'll be asked to decode frames after |
224 // 1. We don't clear |clearExceptFrame|; | 224 // this one. So we want to avoid clearing frames such that those requests |
225 // 2. We don't clear any frame from which a future initFrameBuffer() call | 225 // would force re-decoding from the beginning of the image. |
226 // will copy bitmap data. | 226 // |
227 // All other frames can be cleared. | 227 // When |clearExceptFrame| is e.g. DisposeKeep, simply not clearing that |
| 228 // frame is sufficient, as the next frame will be based on it, and in |
| 229 // general future frames can't be based on anything previous. |
| 230 // |
| 231 // However, if this frame is DisposeOverwritePrevious, then subsequent |
| 232 // frames will depend on this frame's required previous frame. In this |
| 233 // case, we need to preserve both this frame and that one. |
| 234 size_t clearExceptFrame2 = kNotFound; |
| 235 if (clearExceptFrame < m_frameBufferCache.size()) { |
| 236 const ImageFrame& frame = m_frameBufferCache[clearExceptFrame]; |
| 237 if ((frame.status() != ImageFrame::FrameEmpty) && (frame.disposalMethod(
) == ImageFrame::DisposeOverwritePrevious)) { |
| 238 clearExceptFrame2 = clearExceptFrame; |
| 239 clearExceptFrame = frame.requiredPreviousFrameIndex(); |
| 240 } |
| 241 } |
| 242 |
| 243 // Now |clearExceptFrame| indicates the frame that future frames will |
| 244 // depend on. But if decoding is skipping forward past intermediate frames, |
| 245 // this frame may be FrameEmpty. So we need to keep traversing back through |
| 246 // the required previous frames until we find the nearest non-empty |
| 247 // ancestor. Preserving that will minimize the amount of future decoding |
| 248 // needed. |
228 while ((clearExceptFrame < m_frameBufferCache.size()) && (m_frameBufferCache
[clearExceptFrame].status() == ImageFrame::FrameEmpty)) | 249 while ((clearExceptFrame < m_frameBufferCache.size()) && (m_frameBufferCache
[clearExceptFrame].status() == ImageFrame::FrameEmpty)) |
229 clearExceptFrame = m_frameBufferCache[clearExceptFrame].requiredPrevious
FrameIndex(); | 250 clearExceptFrame = m_frameBufferCache[clearExceptFrame].requiredPrevious
FrameIndex(); |
| 251 return clearCacheExceptTwoFrames(clearExceptFrame, clearExceptFrame2); |
| 252 } |
230 | 253 |
231 return ImageDecoder::clearCacheExceptFrame(clearExceptFrame); | 254 |
| 255 size_t GIFImageDecoder::clearCacheExceptTwoFrames(size_t clearExceptFrame1, size
_t clearExceptFrame2) |
| 256 { |
| 257 size_t frameBytesCleared = 0; |
| 258 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) { |
| 259 if (m_frameBufferCache[i].status() != ImageFrame::FrameEmpty && i != cle
arExceptFrame1 && i != clearExceptFrame2) { |
| 260 frameBytesCleared += frameBytesAtIndex(i); |
| 261 clearFrameBuffer(i); |
| 262 } |
| 263 } |
| 264 return frameBytesCleared; |
232 } | 265 } |
233 | 266 |
234 void GIFImageDecoder::clearFrameBuffer(size_t frameIndex) | 267 void GIFImageDecoder::clearFrameBuffer(size_t frameIndex) |
235 { | 268 { |
236 if (m_reader && m_frameBufferCache[frameIndex].status() == ImageFrame::Frame
Partial) { | 269 if (m_reader && m_frameBufferCache[frameIndex].status() == ImageFrame::Frame
Partial) { |
237 // Reset the state of the partial frame in the reader so that the frame | 270 // Reset the state of the partial frame in the reader so that the frame |
238 // can be decoded again when requested. | 271 // can be decoded again when requested. |
239 m_reader->clearDecodeState(frameIndex); | 272 m_reader->clearDecodeState(frameIndex); |
240 } | 273 } |
241 ImageDecoder::clearFrameBuffer(frameIndex); | 274 ImageDecoder::clearFrameBuffer(frameIndex); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 | 368 |
336 // Update our status to be partially complete. | 369 // Update our status to be partially complete. |
337 buffer->setStatus(ImageFrame::FramePartial); | 370 buffer->setStatus(ImageFrame::FramePartial); |
338 | 371 |
339 // Reset the alpha pixel tracker for this frame. | 372 // Reset the alpha pixel tracker for this frame. |
340 m_currentBufferSawAlpha = false; | 373 m_currentBufferSawAlpha = false; |
341 return true; | 374 return true; |
342 } | 375 } |
343 | 376 |
344 } // namespace blink | 377 } // namespace blink |
OLD | NEW |