Convert imgContainerGIF to use nsCOMArray instead of nsSupportsArray. Bug 224621, r=darin, sr=tor.

This commit is contained in:
bryner%brianryner.com 2003-11-04 02:14:11 +00:00
Родитель 96055357ca
Коммит 95de8175be
3 изменённых файлов: 60 добавлений и 87 удалений

Просмотреть файл

@ -32,6 +32,7 @@ FORCE_STATIC_LIB = 1
MODULE_NAME = nsGIFModule2
REQUIRES = xpcom \
string \
gfx \
imglib2 \
$(NULL)

Просмотреть файл

@ -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<gfxIImageFrame> 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<gfxIImageFrame> 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<imgIContainerObserver> observer(do_QueryReferent(mObserver));
if (observer) {
nsCOMPtr<gfxIImageFrame> 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<gfxIImageFrame> 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<gfxIImageFrame> frameToUse;
gfxIImageFrame *frameToUse = nsnull;
if (nextFrameIndex == 0) {
frameToUse = nextFrame;
dirtyRect = mFirstFrameRefreshArea;
} else {
nsCOMPtr<gfxIImageFrame> 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;
}

Просмотреть файл

@ -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 <gfxIImageFrame>s of the GIF
nsSupportsArray mFrames;
nsCOMArray<gfxIImageFrame> 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<nsITimer> mTimer;
nsCOMPtr<nsITimer> mTimer;
/** For managing blending of frames
*
@ -257,7 +241,7 @@ private:
* mLastCompositedFrameIndex to -1. Code assume that if
* mLastCompositedFrameIndex >= 0 then mCompositingFrame exists.
*/
nsCOMPtr<gfxIImageFrame> mCompositingFrame;
nsCOMPtr<gfxIImageFrame> 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<gfxIImageFrame> mCompositingPrevFrame;
nsCOMPtr<gfxIImageFrame> mCompositingPrevFrame;
};
#endif /* __imgContainerGIF_h__ */