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