| 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, Vector<unsigned char>::c
onst_iterator rowBegin, size_t width, size_t rowNumber, unsigned repeatCount, bo
ol writeTransparentPixels) |
| 138 bool GIFImageDecoder::haveDecodedRow(size_t frameIndex, const Vector<unsigned ch
ar>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool write
TransparentPixels) | |
| 139 { | 138 { |
| 140 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); | 139 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); |
| 141 // The pixel data and coordinates supplied to us are relative to the frame's | 140 // The pixel data and coordinates supplied to us are relative to the frame's |
| 142 // origin within the entire image size, i.e. | 141 // origin within the entire image size, i.e. |
| 143 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee | 142 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee |
| 144 // that width == (size().width() - frameContext->xOffset), so | 143 // that width == (size().width() - frameContext->xOffset), so |
| 145 // we must ensure we don't run off the end of either the source data or the | 144 // we must ensure we don't run off the end of either the source data or the |
| 146 // row's X-coordinates. | 145 // row's X-coordinates. |
| 147 const int xBegin = frameContext->xOffset(); | 146 const int xBegin = frameContext->xOffset(); |
| 148 const int yBegin = frameContext->yOffset() + rowNumber; | 147 const int yBegin = frameContext->yOffset() + rowNumber; |
| 149 const int xEnd = std::min(static_cast<int>(frameContext->xOffset() + width),
size().width()); | 148 const int xEnd = std::min(static_cast<int>(frameContext->xOffset() + width),
size().width()); |
| 150 const int yEnd = std::min(static_cast<int>(frameContext->yOffset() + rowNumb
er + repeatCount), size().height()); | 149 const int yEnd = std::min(static_cast<int>(frameContext->yOffset() + rowNumb
er + repeatCount), size().height()); |
| 151 if (rowBuffer.isEmpty() || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin)
|| (yEnd <= yBegin)) | 150 if (!width || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= y
Begin)) |
| 152 return true; | 151 return true; |
| 153 | 152 |
| 154 const GIFColorMap::Table& colorTable = frameContext->localColorMap().isDefin
ed() ? frameContext->localColorMap().table() : m_reader->globalColorMap().table(
); | 153 const GIFColorMap::Table& colorTable = frameContext->localColorMap().isDefin
ed() ? frameContext->localColorMap().table() : m_reader->globalColorMap().table(
); |
| 155 | 154 |
| 156 if (colorTable.isEmpty()) | 155 if (colorTable.isEmpty()) |
| 157 return true; | 156 return true; |
| 158 | 157 |
| 159 GIFColorMap::Table::const_iterator colorTableIter = colorTable.begin(); | 158 GIFColorMap::Table::const_iterator colorTableIter = colorTable.begin(); |
| 160 | 159 |
| 161 // Initialize the frame if necessary. | 160 // Initialize the frame if necessary. |
| 162 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 161 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 163 if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameInd
ex)) | 162 if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameInd
ex)) |
| 164 return false; | 163 return false; |
| 165 | 164 |
| 166 const size_t transparentPixel = frameContext->transparentPixel(); | 165 const size_t transparentPixel = frameContext->transparentPixel(); |
| 167 Vector<unsigned char>::const_iterator rowBegin = rowBuffer.begin(); | |
| 168 Vector<unsigned char>::const_iterator rowEnd = rowBegin + (xEnd - xBegin); | 166 Vector<unsigned char>::const_iterator rowEnd = rowBegin + (xEnd - xBegin); |
| 169 ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin); | 167 ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin); |
| 170 | 168 |
| 171 // We may or may not need to write transparent pixels to the buffer. | 169 // We may or may not need to write transparent pixels to the buffer. |
| 172 // If we're compositing against a previous image, it's wrong, and if | 170 // If we're compositing against a previous image, it's wrong, and if |
| 173 // we're writing atop a cleared, fully transparent buffer, it's | 171 // we're writing atop a cleared, fully transparent buffer, it's |
| 174 // unnecessary; but if we're decoding an interlaced gif and | 172 // unnecessary; but if we're decoding an interlaced gif and |
| 175 // displaying it "Haeberli"-style, we must write these for passes | 173 // displaying it "Haeberli"-style, we must write these for passes |
| 176 // beyond the first, or the initial passes will "show through" the | 174 // beyond the first, or the initial passes will "show through" the |
| 177 // later ones. | 175 // later ones. |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 | 374 |
| 377 // Update our status to be partially complete. | 375 // Update our status to be partially complete. |
| 378 buffer->setStatus(ImageFrame::FramePartial); | 376 buffer->setStatus(ImageFrame::FramePartial); |
| 379 | 377 |
| 380 // Reset the alpha pixel tracker for this frame. | 378 // Reset the alpha pixel tracker for this frame. |
| 381 m_currentBufferSawAlpha = false; | 379 m_currentBufferSawAlpha = false; |
| 382 return true; | 380 return true; |
| 383 } | 381 } |
| 384 | 382 |
| 385 } // namespace WebCore | 383 } // namespace WebCore |
| OLD | NEW |