nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner) { if (mCanceled) return NS_OK; // Were we decoded before? PRBool wasDecoded = PR_FALSE; if (mOwner->GetImageStatus() & imgIRequest::STATUS_FRAME_COMPLETE) wasDecoded = PR_TRUE; // If we're holding locks, unlock the old image. // Note that UnlockImage decrements mLocksHeld each time it's called. PRUint32 oldLockCount = mLocksHeld; while (mLocksHeld) UnlockImage(); // Passing false to aNotify means that mListener will still get // OnStopRequest, if needed. mOwner->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER, PR_FALSE); mOwner = aNewOwner; mOwner->AddProxy(this); // If we were decoded, or if we'd previously requested a decode, request a // decode on the new image if (wasDecoded || mDecodeRequested) mOwner->RequestDecode(); // If we were locked, apply the locks here for (PRUint32 i = 0; i < oldLockCount; i++) LockImage(); return NS_OK; }
EXPORT(IMAGE) CloneImage(IMAGE image) { if (!image) return NULL; IMAGE clone = CreateImage(image->width, image->height, LockImage(image)); UnlockImage(image, false); return clone; }
bool RasterImage::SetMetadata(const ImageMetadata& aMetadata, bool aFromMetadataDecode) { MOZ_ASSERT(NS_IsMainThread()); if (mError) { return true; } if (aMetadata.HasSize()) { IntSize size = aMetadata.GetSize(); if (size.width < 0 || size.height < 0) { NS_WARNING("Image has negative intrinsic size"); DoError(); return true; } MOZ_ASSERT(aMetadata.HasOrientation()); Orientation orientation = aMetadata.GetOrientation(); // If we already have a size, check the new size against the old one. if (mHasSize && (size != mSize || orientation != mOrientation)) { NS_WARNING("Image changed size or orientation on redecode! " "This should not happen!"); DoError(); return true; } // Set the size and flag that we have it. mSize = size; mOrientation = orientation; mHasSize = true; } if (mHasSize && aMetadata.HasAnimation() && !mAnimationState) { // We're becoming animated, so initialize animation stuff. mAnimationState.emplace(mAnimationMode); mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize); // We don't support discarding animated images (See bug 414259). // Lock the image and throw away the key. LockImage(); if (!aFromMetadataDecode) { // The metadata decode reported that this image isn't animated, but we // discovered that it actually was during the full decode. This is a // rare failure that only occurs for corrupt images. To recover, we need // to discard all existing surfaces and redecode. return false; } } if (mAnimationState) { mAnimationState->SetLoopCount(aMetadata.GetLoopCount()); mAnimationState->SetFirstFrameTimeout(aMetadata.GetFirstFrameTimeout()); if (aMetadata.HasLoopLength()) { mAnimationState->SetLoopLength(aMetadata.GetLoopLength()); } if (aMetadata.HasFirstFrameRefreshArea()) { mAnimationState ->SetFirstFrameRefreshArea(aMetadata.GetFirstFrameRefreshArea()); } } if (aMetadata.HasHotspot()) { IntPoint hotspot = aMetadata.GetHotspot(); nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID); nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID); intwrapx->SetData(hotspot.x); intwrapy->SetData(hotspot.y); Set("hotspotX", intwrapx); Set("hotspotY", intwrapy); } return true; }