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

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

Issue 1460523002: GIF decoding to Index8, unit tests and misusing unit test as benchmark (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment #25 processed. Created 4 years, 11 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
OLDNEW
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK ***** 2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * 4 *
5 * The contents of this file are subject to the Mozilla Public License Version 5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with 6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at 7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/ 8 * http://www.mozilla.org/MPL/
9 * 9 *
10 * Software distributed under the License is distributed on an "AS IS" basis, 10 * Software distributed under the License is distributed on an "AS IS" basis,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 138
139 if ((unsigned)drowEnd >= m_frameContext->height()) 139 if ((unsigned)drowEnd >= m_frameContext->height())
140 drowEnd = m_frameContext->height() - 1; 140 drowEnd = m_frameContext->height() - 1;
141 } 141 }
142 142
143 // Protect against too much image data. 143 // Protect against too much image data.
144 if ((unsigned)drowStart >= m_frameContext->height()) 144 if ((unsigned)drowStart >= m_frameContext->height())
145 return true; 145 return true;
146 146
147 // CALLBACK: Let the client know we have decoded a row. 147 // CALLBACK: Let the client know we have decoded a row.
148 if (!m_client->haveDecodedRow(m_frameContext->frameId(), rowBegin, m_frameCo ntext->width(), 148 m_client->haveDecodedRow(*m_frameContext, rowBegin,
149 drowStart, drowEnd - drowStart + 1, m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass > 1)) 149 drowStart, drowEnd - drowStart + 1, m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass > 1);
150 return false;
151 150
152 if (!m_frameContext->interlaced()) 151 if (!m_frameContext->interlaced())
153 irow++; 152 irow++;
154 else { 153 else {
155 do { 154 do {
156 switch (ipass) { 155 switch (ipass) {
157 case 1: 156 case 1:
158 irow += 8; 157 irow += 8;
159 if (irow >= m_frameContext->height()) { 158 if (irow >= m_frameContext->height()) {
160 ipass++; 159 ipass++;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 if (!(avail & codemask) && avail < MAX_DICTIONARY_ENTRIES) { 275 if (!(avail & codemask) && avail < MAX_DICTIONARY_ENTRIES) {
277 ++codesize; 276 ++codesize;
278 codemask += avail; 277 codemask += avail;
279 } 278 }
280 } 279 }
281 oldcode = tempCode; 280 oldcode = tempCode;
282 rowIter += codeLength; 281 rowIter += codeLength;
283 282
284 // Output as many rows as possible. 283 // Output as many rows as possible.
285 GIFRow::iterator rowBegin = rowBuffer.begin(); 284 GIFRow::iterator rowBegin = rowBuffer.begin();
286 for (; rowBegin + width <= rowIter; rowBegin += width) { 285 if (rowBegin + width <= rowIter) {
scroggo_chromium 2016/04/29 19:48:15 These changes (i.e. this if block) might be better
287 if (!outputRow(rowBegin)) 286 for (; rowBegin + width <= rowIter; rowBegin += width) {
288 return false; 287 if (!outputRow(rowBegin))
289 rowsRemaining--; 288 return false;
290 if (!rowsRemaining) 289 rowsRemaining--;
291 return true; 290 if (!rowsRemaining)
292 } 291 return true;
292 }
293 293
294 if (rowBegin != rowBuffer.begin()) {
295 // Move the remaining bytes to the beginning of the buffer. 294 // Move the remaining bytes to the beginning of the buffer.
296 const size_t bytesToCopy = rowIter - rowBegin; 295 const size_t bytesToCopy = rowIter - rowBegin;
297 memcpy(rowBuffer.begin(), rowBegin, bytesToCopy); 296 if (bytesToCopy)
297 memcpy(rowBuffer.begin(), rowBegin, bytesToCopy);
298 rowIter = rowBuffer.begin() + bytesToCopy; 298 rowIter = rowBuffer.begin() + bytesToCopy;
299 } 299 }
300 } 300 }
301 } 301 }
302 return true; 302 return true;
303 } 303 }
304 304
305 void GIFColorMap::buildTable(blink::FastSharedBufferReader* reader) 305 void GIFColorMap::buildTable(blink::FastSharedBufferReader* reader)
306 { 306 {
307 if (!m_isDefined || !m_table.isEmpty()) 307 if (!m_isDefined || !m_table.isEmpty())
(...skipping 27 matching lines...) Expand all
335 335
336 m_lzwContext = adoptPtr(new GIFLZWContext(client, this)); 336 m_lzwContext = adoptPtr(new GIFLZWContext(client, this));
337 if (!m_lzwContext->prepareToDecode()) { 337 if (!m_lzwContext->prepareToDecode()) {
338 m_lzwContext.clear(); 338 m_lzwContext.clear();
339 return false; 339 return false;
340 } 340 }
341 341
342 m_currentLzwBlock = 0; 342 m_currentLzwBlock = 0;
343 } 343 }
344 344
345 if (m_lzwContext->hasRemainingRows()) {
346 if (!client->initFrameBuffer(m_frameId))
scroggo_chromium 2016/04/29 19:48:15 Why is this needed now?
347 return false;
348 }
349
345 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode. 350 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode.
346 while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingR ows()) { 351 while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingR ows()) {
347 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition; 352 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition;
348 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize; 353 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize;
349 if (blockPosition + blockSize > reader->size()) 354 if (blockPosition + blockSize > reader->size())
350 return false; 355 return false;
351 356
352 while (blockSize) { 357 while (blockSize) {
353 const char* segment = 0; 358 const char* segment = 0;
354 size_t segmentLength = reader->getSomeData(segment, blockPosition); 359 size_t segmentLength = reader->getSomeData(segment, blockPosition);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 m_version = 87; 451 m_version = 87;
447 else 452 else
448 return false; 453 return false;
449 GETN(7, GIFGlobalHeader); 454 GETN(7, GIFGlobalHeader);
450 break; 455 break;
451 } 456 }
452 457
453 case GIFGlobalHeader: { 458 case GIFGlobalHeader: {
454 const unsigned char* currentComponent = 459 const unsigned char* currentComponent =
455 reinterpret_cast<const unsigned char*>( 460 reinterpret_cast<const unsigned char*>(
456 reader.getConsecutiveData(currentComponentPosition, 5, readB uffer)); 461 reader.getConsecutiveData(currentComponentPosition, 6, readB uffer));
457 462
458 // This is the height and width of the "screen" or frame into which 463 // This is the height and width of the "screen" or frame into which
459 // images are rendered. The individual images can be smaller than 464 // images are rendered. The individual images can be smaller than
460 // the screen size and located with an origin anywhere within the 465 // the screen size and located with an origin anywhere within the
461 // screen. 466 // screen.
462 // Note that we don't inform the client of the size yet, as it might 467 // Note that we don't inform the client of the size yet, as it might
463 // change after we read the first frame's image header. 468 // change after we read the first frame's image header.
464 m_screenWidth = GETINT16(currentComponent); 469 m_screenWidth = GETINT16(currentComponent);
465 m_screenHeight = GETINT16(currentComponent + 2); 470 m_screenHeight = GETINT16(currentComponent + 2);
466 471
467 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 ); 472 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 );
473 m_backgroundIndex = currentComponent[5];
scroggo_chromium 2016/04/29 19:48:15 It looks like we never looked at this color before
468 474
469 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */ 475 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */
470 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol orMapColors); 476 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol orMapColors);
471 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC olormap); 477 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC olormap);
472 break; 478 break;
473 } 479 }
474 480
475 GETN(1, GIFImageStart); 481 GETN(1, GIFImageStart);
476 break; 482 break;
477 } 483 }
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 rowIter = rowBuffer.begin(); 846 rowIter = rowBuffer.begin();
841 rowsRemaining = m_frameContext->height(); 847 rowsRemaining = m_frameContext->height();
842 848
843 // Clearing the whole suffix table lets us be more tolerant of bad data. 849 // Clearing the whole suffix table lets us be more tolerant of bad data.
844 for (int i = 0; i < clearCode; ++i) { 850 for (int i = 0; i < clearCode; ++i) {
845 suffix[i] = i; 851 suffix[i] = i;
846 suffixLength[i] = 1; 852 suffixLength[i] = 1;
847 } 853 }
848 return true; 854 return true;
849 } 855 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698