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 |