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