Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |