void DeferredImageDecoder::prepareLazyDecodedFrames()
{
    if (!s_enabled
        || !m_actualDecoder
        || !m_actualDecoder->isSizeAvailable()
        || m_actualDecoder->filenameExtension() == "ico")
        return;

    activateLazyDecoding();

    const size_t previousSize = m_lazyDecodedFrames.size();
    m_lazyDecodedFrames.resize(m_actualDecoder->frameCount());
    for (size_t i = previousSize; i < m_lazyDecodedFrames.size(); ++i) {
        OwnPtr<ImageFrame> frame(adoptPtr(new ImageFrame()));
        frame->setSkBitmap(createLazyDecodingBitmap(i));
        frame->setDuration(m_actualDecoder->frameDurationAtIndex(i));
        frame->setStatus(m_actualDecoder->frameIsCompleteAtIndex(i) ? ImageFrame::FrameComplete : ImageFrame::FramePartial);
        m_lazyDecodedFrames[i] = frame.release();
    }

    // The last lazy decoded frame created from previous call might be
    // incomplete so update its state.
    if (previousSize)
        m_lazyDecodedFrames[previousSize - 1]->setStatus(m_actualDecoder->frameIsCompleteAtIndex(previousSize - 1) ? ImageFrame::FrameComplete : ImageFrame::FramePartial);

    if (m_allDataReceived) {
        m_repetitionCount = m_actualDecoder->repetitionCount();
        m_actualDecoder.clear();
        m_data = nullptr;
    }
}
Example #2
0
ImageFrame* DeferredImageDecoder::frameBufferAtIndex(size_t index)
{
    // Only defer image decoding if this is a single frame image. The reason is
    // because a multiframe is usually animated GIF. Animation is handled by
    // BitmapImage which uses some metadata functions that do synchronous image
    // decoding.
    if (s_enabled
        && m_actualDecoder
        && m_actualDecoder->repetitionCount() == cAnimationNone
        && m_actualDecoder->isSizeAvailable()
        && m_actualDecoder->frameCount() == 1) {

        m_size = m_actualDecoder->size();
        m_filenameExtension = m_actualDecoder->filenameExtension();
        m_orientation = m_actualDecoder->orientation();

        SkBitmap lazyDecodedSkBitmap = createLazyDecodingBitmap();
        m_lazyDecodedFrame.setSkBitmap(lazyDecodedSkBitmap);

        // Don't mark the frame as completely decoded until the underlying
        // decoder has really decoded it. Until then, our data and metadata may
        // be incorrect, so callers can't rely on them.
        m_lazyDecodedFrame.setStatus(ImageFrame::FramePartial);
    }

    return m_actualDecoder ? m_actualDecoder->frameBufferAtIndex(index) : &m_lazyDecodedFrame;
}