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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 m_reader->frameContext(index)->isHeaderDefined()) ? | 127 m_reader->frameContext(index)->isHeaderDefined()) ? |
128 m_reader->frameContext(index)->delayTime : 0; | 128 m_reader->frameContext(index)->delayTime : 0; |
129 } | 129 } |
130 | 130 |
131 bool GIFImageDecoder::setFailed() | 131 bool GIFImageDecoder::setFailed() |
132 { | 132 { |
133 m_reader.clear(); | 133 m_reader.clear(); |
134 return ImageDecoder::setFailed(); | 134 return ImageDecoder::setFailed(); |
135 } | 135 } |
136 | 136 |
| 137 // FIXME: Can the intermediate |rowBuffer| be avoided? |
137 bool GIFImageDecoder::haveDecodedRow(size_t frameIndex, const Vector<unsigned ch
ar>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool write
TransparentPixels) | 138 bool GIFImageDecoder::haveDecodedRow(size_t frameIndex, const Vector<unsigned ch
ar>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool write
TransparentPixels) |
138 { | 139 { |
139 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); | 140 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); |
140 // The pixel data and coordinates supplied to us are relative to the frame's | 141 // The pixel data and coordinates supplied to us are relative to the frame's |
141 // origin within the entire image size, i.e. | 142 // origin within the entire image size, i.e. |
142 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee | 143 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee |
143 // that width == (size().width() - frameContext->xOffset), so | 144 // that width == (size().width() - frameContext->xOffset), so |
144 // we must ensure we don't run off the end of either the source data or the | 145 // we must ensure we don't run off the end of either the source data or the |
145 // row's X-coordinates. | 146 // row's X-coordinates. |
146 int xBegin = frameContext->xOffset; | 147 int xBegin = frameContext->xOffset; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 // it had no alpha, and its rect is contained in the current frame's | 236 // it had no alpha, and its rect is contained in the current frame's |
236 // rect, we know the current frame has no alpha. | 237 // rect, we know the current frame has no alpha. |
237 if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgc
olor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevBuff
er->originalFrameRect())) | 238 if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgc
olor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevBuff
er->originalFrameRect())) |
238 buffer.setHasAlpha(false); | 239 buffer.setHasAlpha(false); |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
242 return true; | 243 return true; |
243 } | 244 } |
244 | 245 |
| 246 size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) |
| 247 { |
| 248 // We need to preserve frames such that: |
| 249 // 1. We don't clear |clearExceptFrame|; |
| 250 // 2. We don't clear any frame from which a future initFrameBuffer() call |
| 251 // will copy bitmap data. |
| 252 // All other frames can be cleared. |
| 253 while ((clearExceptFrame < m_frameBufferCache.size()) && (m_frameBufferCache
[clearExceptFrame].status() == ImageFrame::FrameEmpty)) |
| 254 clearExceptFrame = m_frameBufferCache[clearExceptFrame].requiredPrevious
FrameIndex(); |
| 255 |
| 256 return ImageDecoder::clearCacheExceptFrame(clearExceptFrame); |
| 257 } |
| 258 |
245 void GIFImageDecoder::clearFrameBuffer(size_t frameIndex) | 259 void GIFImageDecoder::clearFrameBuffer(size_t frameIndex) |
246 { | 260 { |
247 if (m_reader && m_frameBufferCache[frameIndex].status() == ImageFrame::Frame
Partial) { | 261 if (m_reader && m_frameBufferCache[frameIndex].status() == ImageFrame::Frame
Partial) { |
248 // Reset the state of the partial frame in the reader so that the frame | 262 // Reset the state of the partial frame in the reader so that the frame |
249 // can be decoded again when requested. | 263 // can be decoded again when requested. |
250 m_reader->clearDecodeState(frameIndex); | 264 m_reader->clearDecodeState(frameIndex); |
251 } | 265 } |
252 ImageDecoder::clearFrameBuffer(frameIndex); | 266 ImageDecoder::clearFrameBuffer(frameIndex); |
253 } | 267 } |
254 | 268 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 354 |
341 // Preserve the last frame as the starting state for this frame. | 355 // Preserve the last frame as the starting state for this frame. |
342 if (!buffer->copyBitmapData(*prevBuffer)) | 356 if (!buffer->copyBitmapData(*prevBuffer)) |
343 return setFailed(); | 357 return setFailed(); |
344 | 358 |
345 if (prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgcolor)
{ | 359 if (prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgcolor)
{ |
346 // We want to clear the previous frame to transparent, without | 360 // We want to clear the previous frame to transparent, without |
347 // affecting pixels in the image outside of the frame. | 361 // affecting pixels in the image outside of the frame. |
348 const IntRect& prevRect = prevBuffer->originalFrameRect(); | 362 const IntRect& prevRect = prevBuffer->originalFrameRect(); |
349 ASSERT(!prevRect.contains(IntRect(IntPoint(), size()))); | 363 ASSERT(!prevRect.contains(IntRect(IntPoint(), size()))); |
350 for (int y = prevRect.y(); y < prevRect.maxY(); ++y) { | 364 buffer->zeroFillFrameRect(prevRect); |
351 for (int x = prevRect.x(); x < prevRect.maxX(); ++x) | |
352 buffer->setRGBA(x, y, 0, 0, 0, 0); | |
353 } | |
354 if ((prevRect.width() > 0) && (prevRect.height() > 0)) | |
355 buffer->setHasAlpha(true); | |
356 } | 365 } |
357 } | 366 } |
358 | 367 |
359 // Update our status to be partially complete. | 368 // Update our status to be partially complete. |
360 buffer->setStatus(ImageFrame::FramePartial); | 369 buffer->setStatus(ImageFrame::FramePartial); |
361 | 370 |
362 // Reset the alpha pixel tracker for this frame. | 371 // Reset the alpha pixel tracker for this frame. |
363 m_currentBufferSawAlpha = false; | 372 m_currentBufferSawAlpha = false; |
364 return true; | 373 return true; |
365 } | 374 } |
366 | 375 |
367 } // namespace WebCore | 376 } // namespace WebCore |
OLD | NEW |