// Creates an SkImage that is backed by SkDiscardablePixelRef. PassRefPtr<SkImage> DeferredImageDecoder::createImage(size_t index, bool knownToBeOpaque) const { SkISize decodedSize = m_frameGenerator->getFullSize(); ASSERT(decodedSize.width() > 0); ASSERT(decodedSize.height() > 0); const SkImageInfo info = SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), knownToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, info, index); RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); if (!image) return nullptr; generator->setGenerationId(image->uniqueID()); return image.release(); }
// Creates a SkBitmap that is backed by SkDiscardablePixelRef. SkBitmap DeferredImageDecoder::createBitmap(size_t index) { SkISize decodedSize = m_frameGenerator->getFullSize(); ASSERT(decodedSize.width() > 0); ASSERT(decodedSize.height() > 0); #if SK_B32_SHIFT // Little-endian RGBA pixels. (Android) const SkColorType colorType = kRGBA_8888_SkColorType; #else const SkColorType colorType = kBGRA_8888_SkColorType; #endif const SkImageInfo info = SkImageInfo::Make(decodedSize.width(), decodedSize.height(), colorType, kPremul_SkAlphaType); SkBitmap bitmap; DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, info, index); bool installed = SkInstallDiscardablePixelRef(generator, &bitmap); ASSERT_UNUSED(installed, installed); bitmap.pixelRef()->setURI(labelDiscardable); generator->setGenerationId(bitmap.getGenerationID()); return bitmap; }
sk_sp<SkImage> DeferredImageDecoder::createFrameImageAtIndex( size_t index, bool knownToBeOpaque) { const SkISize& decodedSize = m_frameGenerator->getFullSize(); ASSERT(decodedSize.width() > 0); ASSERT(decodedSize.height() > 0); sk_sp<SkROBuffer> roBuffer(m_rwBuffer->newRBufferSnapshot()); RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkROBuffer(std::move(roBuffer)); SkImageInfo info = SkImageInfo::MakeN32( decodedSize.width(), decodedSize.height(), knownToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType, m_frameGenerator->getColorSpace()); DecodingImageGenerator* generator = new DecodingImageGenerator( m_frameGenerator, info, segmentReader.release(), m_allDataReceived, index, m_frameData[index].m_uniqueID); sk_sp<SkImage> image = SkImage::MakeFromGenerator( generator); // SkImage takes ownership of the generator. if (!image) return nullptr; // We can consider decoded bitmap constant and reuse uniqueID only after all // data is received. We reuse it also for multiframe images when image data // is partially received but the frame data is fully received. if (m_allDataReceived || m_frameData[index].m_isComplete) { DCHECK(m_frameData[index].m_uniqueID == DecodingImageGenerator::kNeedNewImageUniqueID || m_frameData[index].m_uniqueID == image->uniqueID()); m_frameData[index].m_uniqueID = image->uniqueID(); } generator->setCanYUVDecode(m_canYUVDecode); return image; }