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

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

Issue 2495183002: Pull up initFrameBuffer to ImageDecoder. (Closed)
Patch Set: Solved merge conflict with crrev.com/2494363002 Created 4 years, 1 month 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
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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 ? frameContext->localColorMap().getTable() 125 ? frameContext->localColorMap().getTable()
126 : m_reader->globalColorMap().getTable(); 126 : m_reader->globalColorMap().getTable();
127 127
128 if (colorTable.isEmpty()) 128 if (colorTable.isEmpty())
129 return true; 129 return true;
130 130
131 GIFColorMap::Table::const_iterator colorTableIter = colorTable.begin(); 131 GIFColorMap::Table::const_iterator colorTableIter = colorTable.begin();
132 132
133 // Initialize the frame if necessary. 133 // Initialize the frame if necessary.
134 ImageFrame& buffer = m_frameBufferCache[frameIndex]; 134 ImageFrame& buffer = m_frameBufferCache[frameIndex];
135 if ((buffer.getStatus() == ImageFrame::FrameEmpty) && 135 if (!initFrameBuffer(frameIndex))
136 !initFrameBuffer(frameIndex))
137 return false; 136 return false;
138 137
139 const size_t transparentPixel = frameContext->transparentPixel(); 138 const size_t transparentPixel = frameContext->transparentPixel();
140 GIFRow::const_iterator rowEnd = rowBegin + (xEnd - xBegin); 139 GIFRow::const_iterator rowEnd = rowBegin + (xEnd - xBegin);
141 ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin); 140 ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin);
142 141
143 // We may or may not need to write transparent pixels to the buffer. 142 // We may or may not need to write transparent pixels to the buffer.
144 // If we're compositing against a previous image, it's wrong, and if 143 // If we're compositing against a previous image, it's wrong, and if
145 // we're writing atop a cleared, fully transparent buffer, it's 144 // we're writing atop a cleared, fully transparent buffer, it's
146 // unnecessary; but if we're decoding an interlaced gif and 145 // unnecessary; but if we're decoding an interlaced gif and
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 } 182 }
184 183
185 bool GIFImageDecoder::parseCompleted() const { 184 bool GIFImageDecoder::parseCompleted() const {
186 return m_reader && m_reader->parseCompleted(); 185 return m_reader && m_reader->parseCompleted();
187 } 186 }
188 187
189 bool GIFImageDecoder::frameComplete(size_t frameIndex) { 188 bool GIFImageDecoder::frameComplete(size_t frameIndex) {
190 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, 189 // Initialize the frame if necessary. Some GIFs insert do-nothing frames,
191 // in which case we never reach haveDecodedRow() before getting here. 190 // in which case we never reach haveDecodedRow() before getting here.
192 ImageFrame& buffer = m_frameBufferCache[frameIndex]; 191 ImageFrame& buffer = m_frameBufferCache[frameIndex];
193 if ((buffer.getStatus() == ImageFrame::FrameEmpty) && 192 if (!initFrameBuffer(frameIndex))
194 !initFrameBuffer(frameIndex))
195 return false; // initFrameBuffer() has already called setFailed(). 193 return false; // initFrameBuffer() has already called setFailed().
196 194
197 buffer.setStatus(ImageFrame::FrameComplete); 195 buffer.setStatus(ImageFrame::FrameComplete);
198 196
199 if (!m_currentBufferSawAlpha) { 197 if (!m_currentBufferSawAlpha) {
200 // The whole frame was non-transparent, so it's possible that the entire 198 // The whole frame was non-transparent, so it's possible that the entire
201 // resulting buffer was non-transparent, and we can setHasAlpha(false). 199 // resulting buffer was non-transparent, and we can setHasAlpha(false).
202 if (buffer.originalFrameRect().contains(IntRect(IntPoint(), size()))) { 200 if (buffer.originalFrameRect().contains(IntRect(IntPoint(), size()))) {
203 buffer.setHasAlpha(false); 201 buffer.setHasAlpha(false);
204 buffer.setRequiredPreviousFrameIndex(kNotFound); 202 buffer.setRequiredPreviousFrameIndex(kNotFound);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 328
331 if (!m_reader) { 329 if (!m_reader) {
332 m_reader = makeUnique<GIFImageReader>(this); 330 m_reader = makeUnique<GIFImageReader>(this);
333 m_reader->setData(m_data); 331 m_reader->setData(m_data);
334 } 332 }
335 333
336 if (!m_reader->parse(query)) 334 if (!m_reader->parse(query))
337 setFailed(); 335 setFailed();
338 } 336 }
339 337
340 bool GIFImageDecoder::initFrameBuffer(size_t frameIndex) { 338 void GIFImageDecoder::onInitFrameBuffer(size_t frameIndex) {
341 // Initialize the frame rect in our buffer. 339 m_currentBufferSawAlpha = false;
342 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; 340 }
343 341
344 size_t requiredPreviousFrameIndex = buffer->requiredPreviousFrameIndex(); 342 bool GIFImageDecoder::canReusePreviousFrameBuffer(size_t frameIndex) const {
345 if (requiredPreviousFrameIndex == kNotFound) { 343 DCHECK(frameIndex < m_frameBufferCache.size());
346 // This frame doesn't rely on any previous data. 344 return m_frameBufferCache[frameIndex].getDisposalMethod() !=
347 if (!buffer->setSizeAndColorSpace(size().width(), size().height(), 345 ImageFrame::DisposeOverwritePrevious;
348 colorSpace())) { 346 }
349 return setFailed();
350 }
351 } else {
352 ImageFrame* prevBuffer = &m_frameBufferCache[requiredPreviousFrameIndex];
353 ASSERT(prevBuffer->getStatus() == ImageFrame::FrameComplete);
354 347
355 // We try to reuse |prevBuffer| as starting state to avoid copying.
356 // For DisposeOverwritePrevious, the next frame will also use
357 // |prevBuffer| as its starting state, so we can't take over its image
358 // data using takeBitmapDataIfWritable. Copy the data instead.
359 if ((buffer->getDisposalMethod() == ImageFrame::DisposeOverwritePrevious ||
360 !buffer->takeBitmapDataIfWritable(prevBuffer)) &&
361 !buffer->copyBitmapData(*prevBuffer))
362 return setFailed();
363
364 if (prevBuffer->getDisposalMethod() ==
365 ImageFrame::DisposeOverwriteBgcolor) {
366 // We want to clear the previous frame to transparent, without
367 // affecting pixels in the image outside of the frame.
368 const IntRect& prevRect = prevBuffer->originalFrameRect();
369 ASSERT(!prevRect.contains(IntRect(IntPoint(), size())));
370 buffer->zeroFillFrameRect(prevRect);
371 }
372 }
373
374 // Update our status to be partially complete.
375 buffer->setStatus(ImageFrame::FramePartial);
376
377 // Reset the alpha pixel tracker for this frame.
378 m_currentBufferSawAlpha = false;
379 return true;
380 }
381 } // namespace blink 348 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698