void GIFImageDecoder::decode(size_t index)
{
    parse(GIFFrameCountQuery);

    if (failed())
        return;

    updateAggressivePurging(index);

    Vector<size_t> framesToDecode;
    size_t frameToDecode = index;
    do {
        framesToDecode.append(frameToDecode);
        frameToDecode = m_frameBufferCache[frameToDecode].requiredPreviousFrameIndex();
    } while (frameToDecode != kNotFound && m_frameBufferCache[frameToDecode].getStatus() != ImageFrame::FrameComplete);

    for (auto i = framesToDecode.rbegin(); i != framesToDecode.rend(); ++i) {
        if (!m_reader->decode(*i)) {
            setFailed();
            return;
        }

        if (m_purgeAggressively)
            clearCacheExceptFrame(*i);

        // We need more data to continue decoding.
        if (m_frameBufferCache[*i].getStatus() != ImageFrame::FrameComplete)
            break;
    }

    // It is also a fatal error if all data is received and we have decoded all
    // frames available but the file is truncated.
    if (index >= m_frameBufferCache.size() - 1 && isAllDataReceived() && m_reader && !m_reader->parseCompleted())
        setFailed();
}
Example #2
0
bool ImageDecoder::postDecodeProcessing(size_t index) {
  DCHECK(index < m_frameBufferCache.size());

  if (m_frameBufferCache[index].getStatus() != ImageFrame::FrameComplete)
    return false;

  if (m_purgeAggressively)
    clearCacheExceptFrame(index);

  return true;
}
Example #3
0
void WEBPImageDecoder::decode(size_t index) {
  if (failed())
    return;

  Vector<size_t> framesToDecode;
  size_t frameToDecode = index;
  do {
    framesToDecode.append(frameToDecode);
    frameToDecode =
        m_frameBufferCache[frameToDecode].requiredPreviousFrameIndex();
  } while (frameToDecode != kNotFound &&
           m_frameBufferCache[frameToDecode].getStatus() !=
               ImageFrame::FrameComplete);

  ASSERT(m_demux);
  for (auto i = framesToDecode.rbegin(); i != framesToDecode.rend(); ++i) {
    if ((m_formatFlags & ANIMATION_FLAG) && !initFrameBuffer(*i))
      return;
    WebPIterator webpFrame;
    if (!WebPDemuxGetFrame(m_demux, *i + 1, &webpFrame)) {
      setFailed();
    } else {
      decodeSingleFrame(webpFrame.fragment.bytes, webpFrame.fragment.size, *i);
      WebPDemuxReleaseIterator(&webpFrame);
    }
    if (failed())
      return;

    // We need more data to continue decoding.
    if (m_frameBufferCache[*i].getStatus() != ImageFrame::FrameComplete)
      break;

    if (m_purgeAggressively)
      clearCacheExceptFrame(*i);
  }

  // It is also a fatal error if all data is received and we have decoded all
  // frames available but the file is truncated.
  if (index >= m_frameBufferCache.size() - 1 && isAllDataReceived() &&
      m_demux && m_demuxState != WEBP_DEMUX_DONE)
    setFailed();
}