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

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 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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698