| 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 |