Decoder::Decoder(RasterImage* aImage) : mImageData(nullptr) , mImageDataLength(0) , mColormap(nullptr) , mColormapSize(0) , mImage(aImage) , mProgress(NoProgress) , mFrameCount(0) , mFailCode(NS_OK) , mChunkCount(0) , mDecoderFlags(DefaultDecoderFlags()) , mSurfaceFlags(DefaultSurfaceFlags()) , mBytesDecoded(0) , mInitialized(false) , mMetadataDecode(false) , mInFrame(false) , mDataDone(false) , mDecodeDone(false) , mDataError(false) , mDecodeAborted(false) , mShouldReportError(false) { }
NS_IMETHODIMP RasterImage::Decode(const IntSize& aSize, uint32_t aFlags, PlaybackType aPlaybackType) { MOZ_ASSERT(NS_IsMainThread()); if (mError) { return NS_ERROR_FAILURE; } // If we don't have a size yet, we can't do any other decoding. if (!mHasSize) { mWantFullDecode = true; return NS_OK; } // We're about to decode again, which may mean that some of the previous sizes // we've decoded at aren't useful anymore. We can allow them to expire from // the cache by unlocking them here. When the decode finishes, it will send an // invalidation that will cause all instances of this image to redraw. If this // image is locked, any surfaces that are still useful will become locked // again when LookupFrame touches them, and the remainder will eventually // expire. SurfaceCache::UnlockEntries(ImageKey(this)); // Determine which flags we need to decode this image with. DecoderFlags decoderFlags = DefaultDecoderFlags(); if (aFlags & FLAG_ASYNC_NOTIFY) { decoderFlags |= DecoderFlags::ASYNC_NOTIFY; } if (mTransient) { decoderFlags |= DecoderFlags::IMAGE_IS_TRANSIENT; } if (mHasBeenDecoded) { decoderFlags |= DecoderFlags::IS_REDECODE; } SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags); if (IsOpaque()) { // If there's no transparency, it doesn't matter whether we premultiply // alpha or not. surfaceFlags &= ~SurfaceFlags::NO_PREMULTIPLY_ALPHA; } // Create a decoder. RefPtr<IDecodingTask> task; if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) { task = DecoderFactory::CreateAnimationDecoder(mDecoderType, WrapNotNull(this), mSourceBuffer, mSize, decoderFlags, surfaceFlags); } else { task = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this), mSourceBuffer, mSize, aSize, decoderFlags, surfaceFlags, mRequestedSampleSize); } // Make sure DecoderFactory was able to create a decoder successfully. if (!task) { return NS_ERROR_FAILURE; } mDecodeCount++; // We're ready to decode; start the decoder. LaunchDecodingTask(task, this, aFlags, mHasSourceData); return NS_OK; }