Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: Source/core/platform/image-decoders/gif/GIFImageDecoder.cpp

Issue 23646005: Improve GIF decoding performance (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: test data moved to Source/core/platform/image-decoders/testing Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698