| 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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 m_localColorMap.buildTable(reader); | 328 m_localColorMap.buildTable(reader); |
| 329 | 329 |
| 330 *frameDecoded = false; | 330 *frameDecoded = false; |
| 331 if (!m_lzwContext) { | 331 if (!m_lzwContext) { |
| 332 // Wait for more data to properly initialize GIFLZWContext. | 332 // Wait for more data to properly initialize GIFLZWContext. |
| 333 if (!isDataSizeDefined() || !isHeaderDefined()) | 333 if (!isDataSizeDefined() || !isHeaderDefined()) |
| 334 return true; | 334 return true; |
| 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.reset(); |
| 339 return false; | 339 return false; |
| 340 } | 340 } |
| 341 | 341 |
| 342 m_currentLzwBlock = 0; | 342 m_currentLzwBlock = 0; |
| 343 } | 343 } |
| 344 | 344 |
| 345 // Some bad GIFs have extra blocks beyond the last row, which we don't want
to decode. | 345 // 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()) { | 346 while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingR
ows()) { |
| 347 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition; | 347 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition; |
| 348 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize; | 348 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize; |
| 349 if (blockPosition + blockSize > reader->size()) | 349 if (blockPosition + blockSize > reader->size()) |
| 350 return false; | 350 return false; |
| 351 | 351 |
| 352 while (blockSize) { | 352 while (blockSize) { |
| 353 const char* segment = 0; | 353 const char* segment = 0; |
| 354 size_t segmentLength = reader->getSomeData(segment, blockPosition); | 354 size_t segmentLength = reader->getSomeData(segment, blockPosition); |
| 355 size_t decodeSize = std::min(segmentLength, blockSize); | 355 size_t decodeSize = std::min(segmentLength, blockSize); |
| 356 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(segm
ent), decodeSize)) | 356 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(segm
ent), decodeSize)) |
| 357 return false; | 357 return false; |
| 358 blockPosition += decodeSize; | 358 blockPosition += decodeSize; |
| 359 blockSize -= decodeSize; | 359 blockSize -= decodeSize; |
| 360 } | 360 } |
| 361 ++m_currentLzwBlock; | 361 ++m_currentLzwBlock; |
| 362 } | 362 } |
| 363 | 363 |
| 364 // If this frame is data complete then the previous loop must have completel
y decoded all LZW blocks. | 364 // If this frame is data complete then the previous loop must have completel
y decoded all LZW blocks. |
| 365 // There will be no more decoding for this frame so it's time to cleanup. | 365 // There will be no more decoding for this frame so it's time to cleanup. |
| 366 if (isComplete()) { | 366 if (isComplete()) { |
| 367 *frameDecoded = true; | 367 *frameDecoded = true; |
| 368 m_lzwContext.clear(); | 368 m_lzwContext.reset(); |
| 369 } | 369 } |
| 370 return true; | 370 return true; |
| 371 } | 371 } |
| 372 | 372 |
| 373 // Decode a frame. | 373 // Decode a frame. |
| 374 // This method uses GIFFrameContext:decode() to decode the frame; decoding error
is reported to client as a critical failure. | 374 // This method uses GIFFrameContext:decode() to decode the frame; decoding error
is reported to client as a critical failure. |
| 375 // Return true if decoding has progressed. Return false if an error has occurred
. | 375 // Return true if decoding has progressed. Return false if an error has occurred
. |
| 376 bool GIFImageReader::decode(size_t frameIndex) | 376 bool GIFImageReader::decode(size_t frameIndex) |
| 377 { | 377 { |
| 378 blink::FastSharedBufferReader reader(m_data); | 378 blink::FastSharedBufferReader reader(m_data); |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 rowIter = rowBuffer.begin(); | 848 rowIter = rowBuffer.begin(); |
| 849 rowsRemaining = m_frameContext->height(); | 849 rowsRemaining = m_frameContext->height(); |
| 850 | 850 |
| 851 // Clearing the whole suffix table lets us be more tolerant of bad data. | 851 // Clearing the whole suffix table lets us be more tolerant of bad data. |
| 852 for (int i = 0; i < clearCode; ++i) { | 852 for (int i = 0; i < clearCode; ++i) { |
| 853 suffix[i] = i; | 853 suffix[i] = i; |
| 854 suffixLength[i] = 1; | 854 suffixLength[i] = 1; |
| 855 } | 855 } |
| 856 return true; | 856 return true; |
| 857 } | 857 } |
| OLD | NEW |