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 |