Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: Source/core/platform/image-decoders/gif/GIFImageReader.cpp

Issue 15350006: Decode GIF image frames on demand. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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))
Peter Kasting 2013/05/24 03:15:22 Nit: Simpler: return currentFrame->decode(dat
Xianzhu 2013/05/28 22:54:21 Done.
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698