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 a frame. |
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 the frame; decoding error
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(size_t frameIndex) |
| 358 { |
| 359 bool frameDecoded = false; |
| 360 GIFFrameContext* currentFrame = m_frames[frameIndex].get(); |
| 361 |
| 362 if (!currentFrame->decode(data(0), m_data->size(), m_client, &frameDecoded)) |
| 363 return false; |
| 364 |
| 365 if (frameDecoded && !m_client->frameComplete(frameIndex)) |
| 366 return false; |
| 367 |
| 368 return true; |
| 369 } |
| 370 |
| 371 bool GIFImageReader::parse(GIFImageDecoder::GIFParseQuery query) |
358 { | 372 { |
359 ASSERT(m_bytesRead <= m_data->size()); | 373 ASSERT(m_bytesRead <= m_data->size()); |
360 | 374 |
361 if (!parse(m_bytesRead, m_data->size() - m_bytesRead, query == GIFImageDecod
er::GIFSizeQuery)) | 375 return parseData(m_bytesRead, m_data->size() - m_bytesRead, query); |
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; | |
369 GIFFrameContext* currentFrame = m_frames[m_currentDecodingFrame].get(); | |
370 | |
371 if (!currentFrame->decode(data(0), m_data->size(), m_client, &frameDecod
ed)) | |
372 return false; | |
373 | |
374 // We need more data to continue decoding. | |
375 if (!frameDecoded) | |
376 break; | |
377 | |
378 if (!m_client->frameComplete(m_currentDecodingFrame, currentFrame->delay
Time, currentFrame->disposalMethod)) | |
379 return false; | |
380 ++m_currentDecodingFrame; | |
381 } | |
382 | |
383 // All frames decoded. | |
384 if (m_currentDecodingFrame == m_frames.size() && m_parseCompleted) | |
385 m_client->gifComplete(); | |
386 return true; | |
387 } | 376 } |
388 | 377 |
389 // Parse incoming GIF data stream into internal data structures. | 378 // Parse incoming GIF data stream into internal data structures. |
390 // Return true if parsing has progressed or there is not enough data. | 379 // Return true if parsing has progressed or there is not enough data. |
391 // Return false if a fatal error is encountered. | 380 // Return false if a fatal error is encountered. |
392 bool GIFImageReader::parse(size_t dataPosition, size_t len, bool parseSizeOnly) | 381 bool GIFImageReader::parseData(size_t dataPosition, size_t len, GIFImageDecoder:
:GIFParseQuery query) |
393 { | 382 { |
394 if (!len) { | 383 if (!len) { |
395 // No new data has come in since the last call, just ignore this call. | 384 // No new data has come in since the last call, just ignore this call. |
396 return true; | 385 return true; |
397 } | 386 } |
398 | 387 |
399 if (len < m_bytesToConsume) | 388 if (len < m_bytesToConsume) |
400 return true; | 389 return true; |
401 | 390 |
402 // This loop reads as many components from |m_data| as possible. | 391 // 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 } | 658 } |
670 | 659 |
671 // Work around more broken GIF files that have zero image width or h
eight | 660 // Work around more broken GIF files that have zero image width or h
eight |
672 if (!height || !width) { | 661 if (!height || !width) { |
673 height = m_screenHeight; | 662 height = m_screenHeight; |
674 width = m_screenWidth; | 663 width = m_screenWidth; |
675 if (!height || !width) | 664 if (!height || !width) |
676 return false; | 665 return false; |
677 } | 666 } |
678 | 667 |
679 if (parseSizeOnly) { | 668 if (query == GIFImageDecoder::GIFSizeQuery) { |
680 // The decoder needs to stop. Hand back the number of bytes we c
onsumed from | 669 // 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). | 670 // buffer minus 9 (the amount we consumed to read the header). |
682 setRemainingBytes(len + 9); | 671 setRemainingBytes(len + 9); |
683 GETN(9, GIFImageHeader); | 672 GETN(9, GIFImageHeader); |
684 return true; | 673 return true; |
685 } | 674 } |
686 | 675 |
687 addFrameIfNecessary(); | 676 addFrameIfNecessary(); |
688 GIFFrameContext* currentFrame = m_frames.last().get(); | 677 GIFFrameContext* currentFrame = m_frames.last().get(); |
689 | 678 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 rowPosition = 0; | 805 rowPosition = 0; |
817 rowsRemaining = m_frameContext->height; | 806 rowsRemaining = m_frameContext->height; |
818 | 807 |
819 // Clearing the whole suffix table lets us be more tolerant of bad data. | 808 // Clearing the whole suffix table lets us be more tolerant of bad data. |
820 suffix.fill(0); | 809 suffix.fill(0); |
821 for (int i = 0; i < clearCode; i++) | 810 for (int i = 0; i < clearCode; i++) |
822 suffix[i] = i; | 811 suffix[i] = i; |
823 stackp = 0; | 812 stackp = 0; |
824 return true; | 813 return true; |
825 } | 814 } |
OLD | NEW |