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 |