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;
}
Esempio n. 2
0
EXPORT(IMAGE) CloneImage(IMAGE image)
{
    if (!image)
        return NULL;

    IMAGE clone = CreateImage(image->width, image->height, LockImage(image));
    UnlockImage(image, false);

    return clone;
}
Esempio n. 3
0
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;
}