Bug 505385 - Part 13: Remove OnStopContainer and make OnStopDecode a true decode notification. r=joe

This commit is contained in:
Josh Matthews 2012-10-12 12:11:22 -04:00
parent c41e3878e6
commit f905bcf9ea
22 changed files with 62 additions and 167 deletions

View File

@ -134,7 +134,7 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest,
return OnImageIsAnimated(aRequest);
}
if (aType == imgINotificationObserver::STOP_DECODE) {
if (aType == imgINotificationObserver::STOP_REQUEST) {
// We should definitely have a request here
NS_ABORT_IF_FALSE(aRequest, "no request?");
@ -154,27 +154,21 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest,
UpdateImageState(true);
}
if (aType == imgINotificationObserver::STOP_DECODE) {
if (aType == imgINotificationObserver::STOP_REQUEST) {
uint32_t reqStatus;
aRequest->GetImageStatus(&reqStatus);
nsresult status =
reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
return OnStopDecode(aRequest, status);
return OnStopRequest(aRequest, status);
}
return NS_OK;
}
// Warning - This isn't actually fired when decode is complete. Rather, it's
// fired when load is complete. See bug 505385, and in the mean time use
// OnStopContainer.
nsresult
nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
nsresult aStatus)
nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest,
nsresult aStatus)
{
// XXXbholley - When we fix bug 505385, everything here should go in
// OnStopRequest.
// Our state may change. Watch it.
AutoStateChanger changer(this, true);

View File

@ -159,7 +159,7 @@ protected:
nsIContent* aBindingParent, bool aCompileEventHandlers);
void UnbindFromTree(bool aDeep, bool aNullParent);
nsresult OnStopDecode(imgIRequest* aRequest, nsresult aStatus);
nsresult OnStopRequest(imgIRequest* aRequest, nsresult aStatus);
nsresult OnImageIsAnimated(imgIRequest *aRequest);
private:

View File

@ -119,7 +119,7 @@ protected:
float GetZoomLevel();
nsresult OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage);
nsresult OnStopDecode(imgIRequest *aRequest, nsresult aStatus);
nsresult OnStopRequest(imgIRequest *aRequest, nsresult aStatus);
nsCOMPtr<nsIContent> mImageContent;
@ -514,7 +514,7 @@ ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aDa
return OnStartContainer(aRequest, image);
}
if (aType == imgINotificationObserver::STOP_CONTAINER) {
if (aType == imgINotificationObserver::STOP_DECODE) {
if (mImageContent) {
// Update the background-color of the image only after the
// image has been decoded to prevent flashes of just the
@ -533,12 +533,12 @@ ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aDa
}
}
if (aType == imgINotificationObserver::STOP_DECODE) {
if (aType == imgINotificationObserver::STOP_REQUEST) {
uint32_t reqStatus;
aRequest->GetImageStatus(&reqStatus);
nsresult status =
reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
return OnStopDecode(aRequest, status);
return OnStopRequest(aRequest, status);
}
return NS_OK;
@ -558,8 +558,8 @@ ImageDocument::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
}
nsresult
ImageDocument::OnStopDecode(imgIRequest *aRequest,
nsresult aStatus)
ImageDocument::OnStopRequest(imgIRequest *aRequest,
nsresult aStatus)
{
UpdateTitleAndCharset();

View File

@ -5771,7 +5771,7 @@ nsSVGFEImageElement::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRec
container->StartDecoding();
}
if (aType == imgINotificationObserver::STOP_DECODE ||
if (aType == imgINotificationObserver::STOP_REQUEST ||
aType == imgINotificationObserver::FRAME_CHANGED ||
aType == imgINotificationObserver::START_CONTAINER) {
Invalidate();

View File

@ -43,7 +43,7 @@ interface imgIContainer;
* @version 0.1
* @see imagelib2
*/
[scriptable, uuid(5ca71b89-1a2f-475f-881d-d76c1531c4c8)]
[scriptable, uuid(7abf38ca-242b-413a-ab18-80532dd81133)]
interface imgIDecoderObserver : imgIContainerObserver
{
/**
@ -95,11 +95,6 @@ interface imgIDecoderObserver : imgIContainerObserver
*/
void onStopFrame(in imgIRequest aRequest, in unsigned long aFrame);
/**
* Do not implement this. It is useless and going away.
*/
void onStopContainer(in imgIRequest aRequest, in imgIContainer aContainer);
/**
* Notification for when an image is known to be animated. This should be
* fired at the earliest possible time.
@ -118,8 +113,7 @@ interface imgIDecoderObserver : imgIContainerObserver
* revisited in bug 505385. If you're thinking of doing something new with
* this, please talk to bholley first.
*/
void onStopDecode(in imgIRequest aRequest, in nsresult status,
in wstring statusArg);
void onStopDecode(in imgIRequest aRequest, in nsresult status);
/**
* Load notification.

View File

@ -14,7 +14,7 @@ interface imgIRequest;
[ptr] native nsIntRect(nsIntRect);
[scriptable, builtinclass, uuid(bf9ed307-02a5-4732-b3eb-659bde5de84f)]
[scriptable, builtinclass, uuid(9c606ef4-a8e9-45c0-9721-9d6171227ca5)]
interface imgINotificationObserver : nsISupports
{
const long START_REQUEST = 1;
@ -22,7 +22,6 @@ interface imgINotificationObserver : nsISupports
const long START_FRAME = 3;
const long DATA_AVAILABLE = 4;
const long STOP_FRAME = 5;
const long STOP_CONTAINER = 6;
const long STOP_DECODE = 7;
const long DISCARD = 8;
const long IS_ANIMATED = 9;

View File

@ -8,7 +8,7 @@
interface imgIRequest;
[scriptable, uuid(1296bf6c-6067-424b-ba8e-389ec89ee48b)]
[scriptable, uuid(c5a58b5f-cd1f-4c47-a5ed-5013e0b53e95)]
interface imgIScriptedNotificationObserver : nsISupports
{
void startRequest(in imgIRequest aRequest);
@ -17,7 +17,6 @@ interface imgIScriptedNotificationObserver : nsISupports
void startDecode(in imgIRequest aRequest);
void dataAvailable(in imgIRequest aRequest);
void stopFrame(in imgIRequest aRequest);
void stopContainer(in imgIRequest aRequest);
void stopDecode(in imgIRequest aRequest);
void stopRequest(in imgIRequest aRequest);
void discard(in imgIRequest aRequest);

View File

@ -124,8 +124,7 @@ Decoder::Finish()
// Fire teardown notifications
if (mObserver) {
mObserver->OnStopContainer(nullptr, &mImage);
mObserver->OnStopDecode(nullptr, salvage ? NS_OK : NS_ERROR_FAILURE, nullptr);
mObserver->OnStopDecode(nullptr, salvage ? NS_OK : NS_ERROR_FAILURE);
}
}
}
@ -278,8 +277,7 @@ Decoder::PostDecodeDone()
// Notify
mImage.DecodingComplete();
if (mObserver) {
mObserver->OnStopContainer(nullptr, &mImage);
mObserver->OnStopDecode(nullptr, NS_OK, nullptr);
mObserver->OnStopDecode(nullptr, NS_OK);
}
}

View File

@ -43,14 +43,12 @@ ScriptedNotificationObserver::Notify(imgIRequest* aRequest,
return mInner->DataAvailable(aRequest);
if (aType == imgINotificationObserver::STOP_FRAME)
return mInner->StopFrame(aRequest);
if (aType == imgINotificationObserver::STOP_CONTAINER)
return mInner->StopContainer(aRequest);
if (aType == imgINotificationObserver::STOP_DECODE)
return mInner->StopDecode(aRequest);
if (aType == imgINotificationObserver::STOP_REQUEST)
return mInner->StopRequest(aRequest);
if (aType == imgINotificationObserver::DISCARD)
return mInner->StopRequest(aRequest);
return mInner->Discard(aRequest);
if (aType == imgINotificationObserver::IS_ANIMATED)
return mInner->IsAnimated(aRequest);
if (aType == imgINotificationObserver::FRAME_CHANGED)

View File

@ -685,7 +685,7 @@ VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
observer->FrameChanged(nullptr, this, &nsIntRect::GetMaxSizedIntRect());
observer->OnStopFrame(nullptr, 0);
observer->OnStopDecode(nullptr, NS_OK, nullptr);
observer->OnStopDecode(nullptr, NS_OK);
}
EvaluateAnimation();

View File

@ -682,22 +682,7 @@ void imgRequestProxy::OnStopFrame(uint32_t frame)
}
}
void imgRequestProxy::OnStopContainer(imgIContainer *image)
{
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopContainer");
if (mListener && !mCanceled) {
// Hold a ref to the listener while we call it, just in case.
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
mListener->Notify(this, imgINotificationObserver::STOP_CONTAINER, nullptr);
}
// Multipart needs reset for next OnStartContainer
if (mOwner && mOwner->GetMultipart())
mSentStartContainer = false;
}
void imgRequestProxy::OnStopDecode(nsresult status, const PRUnichar *statusArg)
void imgRequestProxy::OnStopDecode()
{
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopDecode");
@ -706,6 +691,10 @@ void imgRequestProxy::OnStopDecode(nsresult status, const PRUnichar *statusArg)
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
mListener->Notify(this, imgINotificationObserver::STOP_DECODE, nullptr);
}
// Multipart needs reset for next OnStartContainer
if (mOwner && mOwner->GetMultipart())
mSentStartContainer = false;
}
void imgRequestProxy::OnDiscard()

View File

@ -137,8 +137,7 @@ protected:
void OnStartFrame (uint32_t aFrame);
void OnDataAvailable (bool aCurrentFrame, const nsIntRect * aRect);
void OnStopFrame (uint32_t aFrame);
void OnStopContainer (imgIContainer *aContainer);
void OnStopDecode (nsresult status, const PRUnichar *statusArg);
void OnStopDecode ();
void OnDiscard ();
void OnImageIsAnimated ();

View File

@ -172,52 +172,29 @@ NS_IMETHODIMP imgStatusTrackerObserver::OnStopFrame(imgIRequest *request,
return NS_OK;
}
/* void onStopContainer (in imgIRequest request, in imgIContainer image); */
NS_IMETHODIMP imgStatusTrackerObserver::OnStopContainer(imgIRequest *request,
imgIContainer *image)
{
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStopContainer");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnDataContainer callback before we've created our image");
mTracker->RecordStopContainer(image);
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopContainer(iter.GetNext(), image);
}
// This is really hacky. We need to handle the case where we start decoding,
// block onload, but then hit an error before we get to our first frame. In
// theory we would just hook in at OnStopDecode, but OnStopDecode is broken
// until we fix bug 505385. OnStopContainer is actually going away at that
// point. So for now we take advantage of the fact that OnStopContainer is
// always fired in the decoders at the same time as OnStopDecode.
mTracker->MaybeUnblockOnload();
return NS_OK;
}
/* void onStopDecode (in imgIRequest request, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP imgStatusTrackerObserver::OnStopDecode(imgIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aStatusArg)
nsresult aStatus)
{
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStopDecode");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnDataDecode callback before we've created our image");
"OnStopDecode callback before we've created our image");
// We finished the decode, and thus have the decoded frames. Update the cache
// entry size to take this into account.
mTracker->GetRequest()->UpdateCacheEntrySize();
mTracker->RecordStopDecode(aStatus, aStatusArg);
mTracker->RecordStopDecode(aStatus);
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopDecode(iter.GetNext(), aStatus, aStatusArg);
mTracker->SendStopDecode(iter.GetNext(), aStatus);
}
// This is really hacky. We need to handle the case where we start decoding,
// block onload, but then hit an error before we get to our first frame.
mTracker->MaybeUnblockOnload();
if (NS_FAILED(aStatus)) {
// Some kind of problem has happened with image decoding.
// Report the URI to net:failed-to-process-uri-conent observers.
@ -230,19 +207,6 @@ NS_IMETHODIMP imgStatusTrackerObserver::OnStopDecode(imgIRequest *aRequest,
}
}
// RasterImage and everything below it is completely correct and
// bulletproof about its handling of decoder notifications.
// Unfortunately, here and above we have to make some gross and
// inappropriate use of things to get things to work without
// completely overhauling the decoder observer interface (this will,
// thankfully, happen in bug 505385). From imgRequest and above (for
// the time being), OnStopDecode is just a companion to OnStopRequest
// that signals success or failure of the _load_ (not the _decode_).
// Within imgStatusTracker, we ignore OnStopDecode notifications from the
// decoder and RasterImage and generate our own every time we send
// OnStopRequest. From within SendStopDecode, we actually send
// OnStopContainer. For more information, see bug 435296.
return NS_OK;
}
@ -513,16 +477,12 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
}
}
// See bug 505385 and imgStatusTrackerObserver::OnStopDecode for more information on why we
// call OnStopContainer based on stateDecodeStopped, and why OnStopDecode is
// called with OnStopRequest.
if (mState & stateDecodeStopped) {
NS_ABORT_IF_FALSE(mImage, "stopped decoding without ever having an image?");
proxy->OnStopContainer(mImage);
proxy->OnStopDecode();
}
if (mState & stateRequestStopped) {
proxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nullptr);
proxy->OnStopRequest(mHadLastPart);
}
}
@ -669,21 +629,7 @@ imgStatusTracker::SendStopFrame(imgRequestProxy* aProxy, uint32_t aFrame)
}
void
imgStatusTracker::RecordStopContainer(imgIContainer* aContainer)
{
NS_ABORT_IF_FALSE(mImage,
"RecordStopContainer called before we have an Image");
// No-op: see imgStatusTrackerObserver::OnStopDecode for more information
}
void
imgStatusTracker::SendStopContainer(imgRequestProxy* aProxy, imgIContainer* aContainer)
{
// No-op: see imgStatusTrackerObserver::OnStopDecode for more information
}
void
imgStatusTracker::RecordStopDecode(nsresult aStatus, const PRUnichar* statusArg)
imgStatusTracker::RecordStopDecode(nsresult aStatus)
{
NS_ABORT_IF_FALSE(mImage,
"RecordStopDecode called before we have an Image");
@ -697,14 +643,10 @@ imgStatusTracker::RecordStopDecode(nsresult aStatus, const PRUnichar* statusArg)
}
void
imgStatusTracker::SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus,
const PRUnichar* statusArg)
imgStatusTracker::SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus)
{
// See imgStatusTrackerObserver::OnStopDecode for more information on why we call
// OnStopContainer from here this, and why imgRequestProxy::OnStopDecode() is
// called from OnStopRequest() and SyncNotify().
if (!aProxy->NotificationsDeferred())
aProxy->OnStopContainer(mImage);
aProxy->OnStopDecode();
}
void
@ -815,10 +757,7 @@ imgStatusTracker::RecordStopRequest(bool aLastPart, nsresult aStatus)
void
imgStatusTracker::SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus)
{
// See bug 505385 and imgStatusTrackerObserver::OnStopDecode for more information on why
// OnStopDecode is called with OnStopRequest.
if (!aProxy->NotificationsDeferred()) {
aProxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nullptr);
aProxy->OnStopRequest(aLastPart);
}
}

View File

@ -145,7 +145,7 @@ public:
void RecordLoaded();
// Shorthand for recording all the decode notifications: StartDecode,
// StartFrame, DataAvailable, StopFrame, StopContainer, StopDecode.
// StartFrame, DataAvailable, StopFrame, StopDecode.
void RecordDecoded();
/* non-virtual imgIDecoderObserver methods */
@ -159,10 +159,8 @@ public:
void SendDataAvailable(imgRequestProxy* aProxy, bool aCurrentFrame, const nsIntRect* aRect);
void RecordStopFrame(uint32_t aFrame);
void SendStopFrame(imgRequestProxy* aProxy, uint32_t aFrame);
void RecordStopContainer(imgIContainer* aContainer);
void SendStopContainer(imgRequestProxy* aProxy, imgIContainer* aContainer);
void RecordStopDecode(nsresult status, const PRUnichar* statusArg);
void SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus, const PRUnichar* statusArg);
void RecordStopDecode(nsresult statusg);
void SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus);
void RecordDiscard();
void SendDiscard(imgRequestProxy* aProxy);
void RecordImageIsAnimated();

View File

@ -129,7 +129,6 @@ function ImageDecoderObserverStub()
this.startContainer = function startContainer(aRequest) {}
this.startFrame = function startFrame(aRequest) {}
this.stopFrame = function stopFrame(aRequest) {}
this.stopContainer = function stopContainer(aRequest) {}
this.stopDecode = function stopDecode(aRequest) {}
this.stopRequest = function stopRequest(aRequest) {}
this.dataAvailable = function dataAvailable(aRequest) {}

View File

@ -58,7 +58,6 @@ function checkAllCallbacks(listener, aRequest)
do_check_neq(listener.state & START_CONTAINER, 0);
do_check_neq(listener.state & START_FRAME, 0);
do_check_neq(listener.state & STOP_FRAME, 0);
do_check_neq(listener.state & STOP_CONTAINER, 0);
do_check_neq(listener.state & STOP_DECODE, 0);
do_check_neq(listener.state & STOP_REQUEST, 0);
do_check_eq(listener.state, ALL_BITS);

View File

@ -11,10 +11,10 @@ const START_DECODE = 0x02;
const START_CONTAINER = 0x04;
const START_FRAME = 0x08;
const STOP_FRAME = 0x10;
const STOP_CONTAINER = 0x20;
const STOP_DECODE = 0x40;
const STOP_REQUEST = 0x80;
const ALL_BITS = 0xFF;
const STOP_DECODE = 0x20;
const STOP_REQUEST = 0x40;
const ALL_BITS = START_REQUEST | START_DECODE | START_CONTAINER | START_FRAME |
STOP_FRAME | STOP_DECODE | STOP_REQUEST;
// An implementation of imgIDecoderObserver with the ability to call specified
// functions on onStartRequest and onStopRequest.
@ -53,12 +53,6 @@ function ImageListener(start_callback, stop_callback)
this.state |= STOP_FRAME;
}
this.stopContainer = function onStopContainer(aRequest)
{
do_check_false(this.synchronous);
this.state |= STOP_CONTAINER;
}
this.stopDecode = function onStopDecode(aRequest)
{
do_check_false(this.synchronous);
@ -69,10 +63,6 @@ function ImageListener(start_callback, stop_callback)
{
do_check_false(this.synchronous);
// onStopDecode must always be called before, and with, onStopRequest. See
// imgRequest::OnStopDecode for more information.
do_check_true(!!(this.state & STOP_DECODE));
// We have to cancel the request when we're done with it to break any
// reference loops!
aRequest.cancelAndForgetObserver(0);

View File

@ -538,12 +538,12 @@ nsImageFrame::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aDat
return OnDataAvailable(aRequest, aData);
}
if (aType == imgINotificationObserver::STOP_DECODE) {
if (aType == imgINotificationObserver::STOP_REQUEST) {
uint32_t imgStatus;
aRequest->GetImageStatus(&imgStatus);
nsresult status =
imgStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
return OnStopDecode(aRequest, status);
return OnStopRequest(aRequest, status);
}
if (aType == imgINotificationObserver::FRAME_CHANGED) {
@ -630,8 +630,8 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
}
nsresult
nsImageFrame::OnStopDecode(imgIRequest *aRequest,
nsresult aStatus)
nsImageFrame::OnStopRequest(imgIRequest *aRequest,
nsresult aStatus)
{
// Check what request type we're dealing with
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);

View File

@ -214,8 +214,8 @@ protected:
friend class nsImageLoadingContent;
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
nsresult OnDataAvailable(imgIRequest *aRequest, const nsIntRect *rect);
nsresult OnStopDecode(imgIRequest *aRequest,
nsresult aStatus);
nsresult OnStopRequest(imgIRequest *aRequest,
nsresult aStatus);
nsresult FrameChanged(imgIRequest *aRequest,
imgIContainer *aContainer);
/**

View File

@ -563,7 +563,7 @@ nsSVGImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect
if (!mFrame)
return NS_ERROR_FAILURE;
if (aType == imgINotificationObserver::STOP_DECODE) {
if (aType == imgINotificationObserver::STOP_REQUEST) {
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
}

View File

@ -586,16 +586,16 @@ nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* a
return OnStartContainer(aRequest, image);
}
if (aType == imgINotificationObserver::STOP_CONTAINER) {
return OnStopContainer(aRequest);
if (aType == imgINotificationObserver::STOP_DECODE) {
return OnStopDecode(aRequest);
}
if (aType == imgINotificationObserver::STOP_DECODE) {
if (aType == imgINotificationObserver::STOP_REQUEST) {
uint32_t imgStatus;
aRequest->GetImageStatus(&imgStatus);
nsresult status =
imgStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
return OnStopDecode(aRequest, status);
return OnStopRequest(aRequest, status);
}
if (aType == imgINotificationObserver::IS_ANIMATED) {
@ -634,7 +634,7 @@ nsresult nsImageBoxFrame::OnStartContainer(imgIRequest *request,
return NS_OK;
}
nsresult nsImageBoxFrame::OnStopContainer(imgIRequest *request)
nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request)
{
nsBoxLayoutState state(PresContext());
this->Redraw(state);
@ -642,8 +642,8 @@ nsresult nsImageBoxFrame::OnStopContainer(imgIRequest *request)
return NS_OK;
}
nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request,
nsresult aStatus)
nsresult nsImageBoxFrame::OnStopRequest(imgIRequest *request,
nsresult aStatus)
{
if (NS_SUCCEEDED(aStatus))
// Fire an onload DOM event.

View File

@ -95,8 +95,8 @@ protected:
private:
nsresult OnStartContainer(imgIRequest *request, imgIContainer *image);
nsresult OnStopContainer(imgIRequest *request);
nsresult OnStopDecode(imgIRequest *request, nsresult status);
nsresult OnStopDecode(imgIRequest *request);
nsresult OnStopRequest(imgIRequest *request, nsresult status);
nsresult OnImageIsAnimated(imgIRequest* aRequest);
nsresult FrameChanged(imgIRequest *aRequest);