From 95de8175bed988f358e80a336af78fcb44318163 Mon Sep 17 00:00:00 2001 From: "bryner%brianryner.com" Date: Tue, 4 Nov 2003 02:14:11 +0000 Subject: [PATCH] Convert imgContainerGIF to use nsCOMArray instead of nsSupportsArray. Bug 224621, r=darin, sr=tor. --- modules/libpr0n/decoders/gif/Makefile.in | 1 + .../libpr0n/decoders/gif/imgContainerGIF.cpp | 84 ++++++++----------- .../libpr0n/decoders/gif/imgContainerGIF.h | 62 +++++--------- 3 files changed, 60 insertions(+), 87 deletions(-) diff --git a/modules/libpr0n/decoders/gif/Makefile.in b/modules/libpr0n/decoders/gif/Makefile.in index bec77be1f4e..affed73912a 100644 --- a/modules/libpr0n/decoders/gif/Makefile.in +++ b/modules/libpr0n/decoders/gif/Makefile.in @@ -32,6 +32,7 @@ FORCE_STATIC_LIB = 1 MODULE_NAME = nsGIFModule2 REQUIRES = xpcom \ + string \ gfx \ imglib2 \ $(NULL) diff --git a/modules/libpr0n/decoders/gif/imgContainerGIF.cpp b/modules/libpr0n/decoders/gif/imgContainerGIF.cpp index 43be428da64..ed30e31d9d6 100644 --- a/modules/libpr0n/decoders/gif/imgContainerGIF.cpp +++ b/modules/libpr0n/decoders/gif/imgContainerGIF.cpp @@ -55,9 +55,6 @@ imgContainerGIF::~imgContainerGIF() { if (mTimer) mTimer->Cancel(); - - /* destructor code */ - mFrames.Clear(); } //****************************************************************************** @@ -106,14 +103,19 @@ NS_IMETHODIMP imgContainerGIF::GetHeight(nscoord *aHeight) /* readonly attribute gfxIImageFrame currentFrame; */ NS_IMETHODIMP imgContainerGIF::GetCurrentFrame(gfxIImageFrame * *aCurrentFrame) { - return inlinedGetCurrentFrame(aCurrentFrame); + if (!(*aCurrentFrame = inlinedGetCurrentFrame())) + return NS_ERROR_FAILURE; + + NS_ADDREF(*aCurrentFrame); + return NS_OK; } //****************************************************************************** /* readonly attribute unsigned long numFrames; */ NS_IMETHODIMP imgContainerGIF::GetNumFrames(PRUint32 *aNumFrames) { - return mFrames.Count(aNumFrames); + *aNumFrames = mFrames.Count(); + return NS_OK; } //****************************************************************************** @@ -121,7 +123,11 @@ NS_IMETHODIMP imgContainerGIF::GetNumFrames(PRUint32 *aNumFrames) NS_IMETHODIMP imgContainerGIF::GetFrameAt(PRUint32 index, gfxIImageFrame **_retval) { - return inlinedGetFrameAt(index, _retval); + if (!(*_retval = mFrames[index])) + return NS_ERROR_FAILURE; + + NS_ADDREF(*_retval); + return NS_OK; } //****************************************************************************** @@ -132,7 +138,7 @@ NS_IMETHODIMP imgContainerGIF::AppendFrame(gfxIImageFrame *item) if (!item) return NS_ERROR_NULL_POINTER; - PRUint32 numFrames = inlinedGetNumFrames(); + PRInt32 numFrames = mFrames.Count(); if (numFrames == 0) { // First Frame // If we dispose of the first frame by clearing it, then the @@ -152,7 +158,7 @@ NS_IMETHODIMP imgContainerGIF::AppendFrame(gfxIImageFrame *item) mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, itemRect); } - mFrames.AppendElement(NS_STATIC_CAST(nsISupports*, item)); + mFrames.AppendObject(item); // If this is our second frame, start the animation. // Must be called after AppendElement because StartAnimation checks for > 1 @@ -188,19 +194,16 @@ NS_IMETHODIMP imgContainerGIF::DecodingComplete(void) mDoneDecoding = PR_TRUE; // If there's only 1 frame, optimize it. // Optimizing animated gifs is not supported - PRUint32 numFrames = inlinedGetNumFrames(); - if (numFrames == 1) { - nsCOMPtr currentFrame; - inlinedGetFrameAt(0, getter_AddRefs(currentFrame)); - currentFrame->SetMutable(PR_FALSE); - } + if (mFrames.Count() == 1) + mFrames[0]->SetMutable(PR_FALSE); return NS_OK; } /* void clear (); */ NS_IMETHODIMP imgContainerGIF::Clear() { - return mFrames.Clear(); + mFrames.Clear(); + return NS_OK; } //****************************************************************************** @@ -243,12 +246,9 @@ NS_IMETHODIMP imgContainerGIF::StartAnimation() if (mAnimationMode == kDontAnimMode || mAnimating || mTimer) return NS_OK; - PRUint32 numFrames = inlinedGetNumFrames(); - if (numFrames > 1) { + if (mFrames.Count() > 1) { PRInt32 timeout; - nsCOMPtr currentFrame; - - inlinedGetCurrentFrame(getter_AddRefs(currentFrame)); + gfxIImageFrame *currentFrame = inlinedGetCurrentFrame(); if (currentFrame) { currentFrame->GetTimeout(&timeout); if (timeout <= 0) // -1 means display this frame forever @@ -304,11 +304,8 @@ NS_IMETHODIMP imgContainerGIF::ResetAnimation() mCurrentAnimationFrameIndex = 0; // Update display nsCOMPtr observer(do_QueryReferent(mObserver)); - if (observer) { - nsCOMPtr firstFrame; - inlinedGetFrameAt(0, getter_AddRefs(firstFrame)); - observer->FrameChanged(this, firstFrame, &mFirstFrameRefreshArea); - } + if (observer) + observer->FrameChanged(this, mFrames[0], &mFirstFrameRefreshArea); if (oldAnimating) return StartAnimation(); @@ -353,11 +350,11 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer) return NS_OK; } - PRInt32 numFrames = inlinedGetNumFrames(); + PRInt32 numFrames = mFrames.Count(); if (!numFrames) return NS_OK; - nsCOMPtr nextFrame; + gfxIImageFrame *nextFrame = nsnull; PRInt32 previousFrameIndex = mCurrentAnimationFrameIndex; PRInt32 nextFrameIndex = mCurrentAnimationFrameIndex + 1; PRInt32 timeout = 0; @@ -384,8 +381,7 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer) mLoopCount--; } - if (NS_FAILED(inlinedGetFrameAt(nextFrameIndex, - getter_AddRefs(nextFrame)))) { + if (!(nextFrame = mFrames[nextFrameIndex])) { // something wrong with the next frame, skip it mCurrentAnimationFrameIndex = nextFrameIndex; mTimer->SetDelay(100); @@ -403,8 +399,7 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer) // that hasn't been decoded yet, go back to the last frame decoded NS_WARNING("imgContainerGIF::Notify() Frame is passed decoded frame"); nextFrameIndex = mCurrentDecodingFrameIndex; - if (NS_FAILED(inlinedGetFrameAt(nextFrameIndex, - getter_AddRefs(nextFrame)))) { + if (!(nextFrame = mFrames[nextFrameIndex])) { // something wrong with the next frame, skip it mCurrentAnimationFrameIndex = nextFrameIndex; mTimer->SetDelay(100); @@ -419,20 +414,19 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer) StopAnimation(); nsRect dirtyRect; - nsCOMPtr frameToUse; + gfxIImageFrame *frameToUse = nsnull; if (nextFrameIndex == 0) { frameToUse = nextFrame; dirtyRect = mFirstFrameRefreshArea; } else { - nsCOMPtr prevFrame; - if (NS_FAILED(inlinedGetFrameAt(previousFrameIndex, - getter_AddRefs(prevFrame)))) + gfxIImageFrame *prevFrame = mFrames[previousFrameIndex]; + if (!prevFrame) return NS_OK; // Change frame and announce it - if (NS_FAILED(DoComposite(getter_AddRefs(frameToUse), &dirtyRect, - prevFrame, nextFrame, nextFrameIndex))) { + if (NS_FAILED(DoComposite(&frameToUse, &dirtyRect, prevFrame, + nextFrame, nextFrameIndex))) { // something went wrong, move on to next NS_WARNING("imgContainerGIF: Composing Frame Failed\n"); mCurrentAnimationFrameIndex = nextFrameIndex; @@ -449,11 +443,11 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer) //****************************************************************************** // DoComposite gets called when the timer for animation get fired and we have to // update the composited frame of the animation. -NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse, - nsRect* aDirtyRect, - gfxIImageFrame* aPrevFrame, - gfxIImageFrame* aNextFrame, - PRInt32 aNextFrameIndex) +nsresult imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse, + nsRect* aDirtyRect, + gfxIImageFrame* aPrevFrame, + gfxIImageFrame* aNextFrame, + PRInt32 aNextFrameIndex) { NS_ASSERTION(aDirtyRect, "imgContainerGIF::DoComposite aDirtyRect is null"); NS_ASSERTION(aPrevFrame, "imgContainerGIF::DoComposite aPrevFrame is null"); @@ -472,7 +466,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse, if (prevFrameDisposalMethod == DISPOSE_CLEAR_ALL) { aDirtyRect->SetRect(0, 0, mSize.width, mSize.height); *aFrameToUse = aNextFrame; - NS_ADDREF(*aFrameToUse); return NS_OK; } @@ -487,7 +480,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse, if (isFullPrevFrame && prevFrameDisposalMethod == DISPOSE_CLEAR) { aDirtyRect->SetRect(0, 0, mSize.width, mSize.height); *aFrameToUse = aNextFrame; - NS_ADDREF(*aFrameToUse); return NS_OK; } @@ -511,7 +503,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse, aDirtyRect->SetRect(0, 0, mSize.width, mSize.height); *aFrameToUse = aNextFrame; - NS_ADDREF(*aFrameToUse); return NS_OK; } @@ -547,7 +538,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse, // since it's still sitting in mCompositingFrame) if (mLastCompositedFrameIndex == aNextFrameIndex) { *aFrameToUse = mCompositingFrame; - NS_ADDREF(*aFrameToUse); return NS_OK; } @@ -670,14 +660,12 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse, aPrevFrame->SetFrameDisposalMethod(DISPOSE_CLEAR_ALL); mLastCompositedFrameIndex = -1; *aFrameToUse = aNextFrame; - NS_ADDREF(*aFrameToUse); return NS_OK; } } mLastCompositedFrameIndex = aNextFrameIndex; *aFrameToUse = mCompositingFrame; - NS_ADDREF(*aFrameToUse); return NS_OK; } diff --git a/modules/libpr0n/decoders/gif/imgContainerGIF.h b/modules/libpr0n/decoders/gif/imgContainerGIF.h index acc2829e349..c556dc8695e 100644 --- a/modules/libpr0n/decoders/gif/imgContainerGIF.h +++ b/modules/libpr0n/decoders/gif/imgContainerGIF.h @@ -32,7 +32,7 @@ #include "imgIContainerObserver.h" #include "imgIContainer.h" -#include "nsSupportsArray.h" +#include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsITimer.h" #include "imgIDecoderObserver.h" @@ -130,27 +130,11 @@ private: DISPOSE_RESTORE_PREVIOUS = 3 //!< Restore the previous (composited) frame }; - inline PRUint32 inlinedGetNumFrames() { - PRUint32 nframes; - mFrames.Count(&nframes); - return nframes; - } + inline gfxIImageFrame* inlinedGetCurrentFrame() { + if (mLastCompositedFrameIndex == mCurrentAnimationFrameIndex) + return mCompositingFrame; - inline nsresult inlinedGetFrameAt(PRUint32 index, gfxIImageFrame **_retval) { - // callers DO try to go past the end - nsISupports *_elem = mFrames.ElementAt(index); - if (!_elem) return NS_ERROR_FAILURE; - *_retval = NS_STATIC_CAST(gfxIImageFrame*, _elem); - return NS_OK; - } - - inline nsresult inlinedGetCurrentFrame(gfxIImageFrame **_retval) { - if (mLastCompositedFrameIndex == mCurrentAnimationFrameIndex) { - *_retval = mCompositingFrame; - NS_ADDREF(*_retval); - return NS_OK; - } - return inlinedGetFrameAt(mCurrentAnimationFrameIndex, _retval); + return mFrames[mCurrentAnimationFrameIndex]; } /** Function for doing the frame compositing of animations @@ -162,10 +146,10 @@ private: * @param aNextFrame Frame we need to incorperate/display * @param aNextFrameIndex Position of aNextFrame in mFrames list */ - NS_IMETHODIMP DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect, - gfxIImageFrame* aPrevFrame, - gfxIImageFrame* aNextFrame, - PRInt32 aNextFrameIndex); + nsresult DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect, + gfxIImageFrame* aPrevFrame, + gfxIImageFrame* aNextFrame, + PRInt32 aNextFrameIndex); /** * Combine aOverlayFrame's mask into aCompositingFrame's mask. @@ -221,33 +205,33 @@ private: //! imgIContainerObserver; used for telling observers that the frame changed - nsWeakPtr mObserver; + nsWeakPtr mObserver; //! All the s of the GIF - nsSupportsArray mFrames; + nsCOMArray mFrames; //! Size of GIF (not necessarily the frame) - nsSize mSize; + nsSize mSize; //! Area of the first frame that needs to be redrawn on subsequent loops - nsRect mFirstFrameRefreshArea; + nsRect mFirstFrameRefreshArea; - PRInt32 mCurrentDecodingFrameIndex; // 0 to numFrames-1 - PRInt32 mCurrentAnimationFrameIndex; // 0 to numFrames-1 + PRInt32 mCurrentDecodingFrameIndex; // 0 to numFrames-1 + PRInt32 mCurrentAnimationFrameIndex; // 0 to numFrames-1 //! Track the last composited frame for Optimizations (See DoComposite code) - PRInt32 mLastCompositedFrameIndex; + PRInt32 mLastCompositedFrameIndex; //! Whether we can assume there will be no more frames //! (and thus loop the animation) - PRBool mDoneDecoding; + PRBool mDoneDecoding; //! Are we currently animating the GIF? - PRBool mAnimating; + PRBool mAnimating; //! See imgIContainer for mode constants - PRUint16 mAnimationMode; + PRUint16 mAnimationMode; //! # loops remaining before animation stops (-1 no stop) - PRInt32 mLoopCount; + PRInt32 mLoopCount; //! Timer to animate multiframed images - nsCOMPtr mTimer; + nsCOMPtr mTimer; /** For managing blending of frames * @@ -257,7 +241,7 @@ private: * mLastCompositedFrameIndex to -1. Code assume that if * mLastCompositedFrameIndex >= 0 then mCompositingFrame exists. */ - nsCOMPtr mCompositingFrame; + nsCOMPtr mCompositingFrame; /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS * @@ -265,7 +249,7 @@ private: * stored in cases where the GIF specifies it wants the last frame back * when it's done with the current frame. */ - nsCOMPtr mCompositingPrevFrame; + nsCOMPtr mCompositingPrevFrame; }; #endif /* __imgContainerGIF_h__ */