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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 | 344 |
| 345 // If this frame is data complete then the previous loop must have completel y decoded all LZW blocks. | 345 // If this frame is data complete then the previous loop must have completel y decoded all LZW blocks. |
| 346 // There will be no more decoding for this frame so it's time to cleanup. | 346 // There will be no more decoding for this frame so it's time to cleanup. |
| 347 if (isComplete()) { | 347 if (isComplete()) { |
| 348 *frameDecoded = true; | 348 *frameDecoded = true; |
| 349 m_lzwContext.clear(); | 349 m_lzwContext.clear(); |
| 350 } | 350 } |
| 351 return true; | 351 return true; |
| 352 } | 352 } |
| 353 | 353 |
| 354 // Decode all frames before haltAtFrame. | 354 // Decode frames. The frames must have been parsed. |
| 355 // This method uses GIFFrameContext:decode() to decode each frame; decoding erro r is reported to client as a critical failure. | 355 // This method uses GIFFrameContext:decode() to decode each frame; decoding erro r is reported to client as a critical failure. |
| 356 // Return true if decoding has progressed. Return false if an error has occurred . | 356 // Return true if decoding has progressed. Return false if an error has occurred . |
| 357 bool GIFImageReader::decode(GIFImageDecoder::GIFQuery query, unsigned haltAtFram e) | 357 bool GIFImageReader::decode(const BitVector& frames) |
| 358 { | 358 { |
| 359 ASSERT(m_bytesRead <= m_data->size()); | 359 for (size_t i = 0; i < frames.size(); ++i) { |
|
Alpha Left Google
2013/05/18 00:39:35
I would rather let the user of this API to call mu
Xianzhu
2013/05/20 04:30:59
Done.
| |
| 360 if (!frames.get(i)) | |
| 361 continue; | |
| 360 | 362 |
| 361 if (!parse(m_bytesRead, m_data->size() - m_bytesRead, query == GIFImageDecod er::GIFSizeQuery)) | |
| 362 return false; | |
| 363 | |
| 364 if (query != GIFImageDecoder::GIFFullQuery) | |
| 365 return true; | |
| 366 | |
| 367 while (m_currentDecodingFrame < std::min(m_frames.size(), static_cast<size_t >(haltAtFrame))) { | |
| 368 bool frameDecoded = false; | 363 bool frameDecoded = false; |
| 369 GIFFrameContext* currentFrame = m_frames[m_currentDecodingFrame].get(); | 364 GIFFrameContext* currentFrame = m_frames[i].get(); |
| 370 | 365 |
| 371 if (!currentFrame->decode(data(0), m_data->size(), m_client, &frameDecod ed)) | 366 if (!currentFrame->decode(data(0), m_data->size(), m_client, &frameDecod ed)) |
| 372 return false; | 367 return false; |
| 373 | 368 |
| 374 // We need more data to continue decoding. | 369 // We need more data to continue decoding. |
| 375 if (!frameDecoded) | 370 if (!frameDecoded) |
| 376 break; | 371 break; |
| 377 | 372 |
| 378 if (!m_client->frameComplete(m_currentDecodingFrame, currentFrame->delay Time, currentFrame->disposalMethod)) | 373 if (!m_client->frameComplete(i, currentFrame->delayTime, currentFrame->d isposalMethod)) |
| 379 return false; | 374 return false; |
| 380 ++m_currentDecodingFrame; | 375 |
| 376 m_decodedFramesCount++; | |
|
Alpha Left Google
2013/05/18 00:39:35
See my comments below, I don't think we need to do
Xianzhu
2013/05/20 04:30:59
Done.
| |
| 381 } | 377 } |
| 382 | 378 |
| 383 // All frames decoded. | 379 // All frames decoded. |
| 384 if (m_currentDecodingFrame == m_frames.size() && m_parseCompleted) | 380 if (m_decodedFramesCount == m_frames.size() && m_parseCompleted) |
|
Alpha Left Google
2013/05/18 00:39:35
This check will not be correct because we now allo
Xianzhu
2013/05/20 04:30:59
Done.
| |
| 385 m_client->gifComplete(); | 381 m_client->gifComplete(); |
| 386 return true; | 382 return true; |
| 387 } | 383 } |
| 388 | 384 |
| 385 bool GIFImageReader::parse(GIFImageDecoder::GIFParseQuery query) | |
| 386 { | |
| 387 ASSERT(m_bytesRead <= m_data->size()); | |
| 388 | |
| 389 return parseData(m_bytesRead, m_data->size() - m_bytesRead, query); | |
| 390 } | |
| 391 | |
| 389 // Parse incoming GIF data stream into internal data structures. | 392 // Parse incoming GIF data stream into internal data structures. |
| 390 // Return true if parsing has progressed or there is not enough data. | 393 // Return true if parsing has progressed or there is not enough data. |
| 391 // Return false if a fatal error is encountered. | 394 // Return false if a fatal error is encountered. |
| 392 bool GIFImageReader::parse(size_t dataPosition, size_t len, bool parseSizeOnly) | 395 bool GIFImageReader::parseData(size_t dataPosition, size_t len, GIFImageDecoder: :GIFParseQuery query) |
| 393 { | 396 { |
| 394 if (!len) { | 397 if (!len) { |
| 395 // No new data has come in since the last call, just ignore this call. | 398 // No new data has come in since the last call, just ignore this call. |
| 396 return true; | 399 return true; |
| 397 } | 400 } |
| 398 | 401 |
| 399 if (len < m_bytesToConsume) | 402 if (len < m_bytesToConsume) |
| 400 return true; | 403 return true; |
| 401 | 404 |
| 402 // This loop reads as many components from |m_data| as possible. | 405 // This loop reads as many components from |m_data| as possible. |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 669 } | 672 } |
| 670 | 673 |
| 671 // Work around more broken GIF files that have zero image width or h eight | 674 // Work around more broken GIF files that have zero image width or h eight |
| 672 if (!height || !width) { | 675 if (!height || !width) { |
| 673 height = m_screenHeight; | 676 height = m_screenHeight; |
| 674 width = m_screenWidth; | 677 width = m_screenWidth; |
| 675 if (!height || !width) | 678 if (!height || !width) |
| 676 return false; | 679 return false; |
| 677 } | 680 } |
| 678 | 681 |
| 679 if (parseSizeOnly) { | 682 if (query == GIFImageDecoder::GIFSizeQuery) { |
| 680 // The decoder needs to stop. Hand back the number of bytes we c onsumed from | 683 // The decoder needs to stop. Hand back the number of bytes we c onsumed from |
| 681 // buffer minus 9 (the amount we consumed to read the header). | 684 // buffer minus 9 (the amount we consumed to read the header). |
| 682 setRemainingBytes(len + 9); | 685 setRemainingBytes(len + 9); |
| 683 GETN(9, GIFImageHeader); | 686 GETN(9, GIFImageHeader); |
| 684 return true; | 687 return true; |
| 685 } | 688 } |
| 686 | 689 |
| 687 addFrameIfNecessary(); | 690 addFrameIfNecessary(); |
| 688 GIFFrameContext* currentFrame = m_frames.last().get(); | 691 GIFFrameContext* currentFrame = m_frames.last().get(); |
| 689 | 692 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 816 rowPosition = 0; | 819 rowPosition = 0; |
| 817 rowsRemaining = m_frameContext->height; | 820 rowsRemaining = m_frameContext->height; |
| 818 | 821 |
| 819 // Clearing the whole suffix table lets us be more tolerant of bad data. | 822 // Clearing the whole suffix table lets us be more tolerant of bad data. |
| 820 suffix.fill(0); | 823 suffix.fill(0); |
| 821 for (int i = 0; i < clearCode; i++) | 824 for (int i = 0; i < clearCode; i++) |
| 822 suffix[i] = i; | 825 suffix[i] = i; |
| 823 stackp = 0; | 826 stackp = 0; |
| 824 return true; | 827 return true; |
| 825 } | 828 } |
| OLD | NEW |