diff --git a/modules/libpr0n/src/Image.cpp b/modules/libpr0n/src/Image.cpp index 886097d3e2b9..75d0c4cba01f 100644 --- a/modules/libpr0n/src/Image.cpp +++ b/modules/libpr0n/src/Image.cpp @@ -41,10 +41,15 @@ namespace mozilla { namespace imagelib { // Constructor -Image::Image() : - mStatusTracker(this), +Image::Image(imgStatusTracker* aStatusTracker) : mInitialized(PR_FALSE) { + if (aStatusTracker) { + mStatusTracker = aStatusTracker; + mStatusTracker->SetImage(this); + } else { + mStatusTracker = new imgStatusTracker(this); + } } // Translates a mimetype into a concrete decoder diff --git a/modules/libpr0n/src/Image.h b/modules/libpr0n/src/Image.h index 3c7709c9a14a..1e807364f637 100644 --- a/modules/libpr0n/src/Image.h +++ b/modules/libpr0n/src/Image.h @@ -48,7 +48,7 @@ namespace imagelib { class Image : public imgIContainer { public: - imgStatusTracker& GetStatusTracker() { return mStatusTracker; } + imgStatusTracker& GetStatusTracker() { return *mStatusTracker; } PRBool IsInitialized() const { return mInitialized; } /** @@ -108,11 +108,11 @@ public: static eDecoderType GetDecoderType(const char *aMimeType); protected: - Image(); + Image(imgStatusTracker* aStatusTracker); // Member data shared by all implementations of this abstract class - imgStatusTracker mStatusTracker; - PRPackedBool mInitialized; // Have we been initalized? + nsAutoPtr mStatusTracker; + PRPackedBool mInitialized; // Have we been initalized? }; } // namespace imagelib diff --git a/modules/libpr0n/src/RasterImage.cpp b/modules/libpr0n/src/RasterImage.cpp index 83954eb55cd9..4ff3397e4b51 100644 --- a/modules/libpr0n/src/RasterImage.cpp +++ b/modules/libpr0n/src/RasterImage.cpp @@ -149,7 +149,8 @@ NS_IMPL_ISUPPORTS4(RasterImage, imgIContainer, nsITimerCallback, nsIProperties, nsISupportsWeakReference) //****************************************************************************** -RasterImage::RasterImage() : +RasterImage::RasterImage(imgStatusTracker* aStatusTracker) : + Image(aStatusTracker), // invoke superclass's constructor mSize(0,0), mAnim(nsnull), mAnimationMode(kNormalAnimMode), @@ -342,8 +343,8 @@ RasterImage::ExtractFrame(PRUint32 aWhichFrame, img->mFrames.AppendElement(subframe.forget()); - img->mStatusTracker.RecordLoaded(); - img->mStatusTracker.RecordDecoded(); + img->mStatusTracker->RecordLoaded(); + img->mStatusTracker->RecordDecoded(); *_retval = img.forget().get(); diff --git a/modules/libpr0n/src/RasterImage.h b/modules/libpr0n/src/RasterImage.h index 5b4664bbb5cf..69fcf55afb1d 100644 --- a/modules/libpr0n/src/RasterImage.h +++ b/modules/libpr0n/src/RasterImage.h @@ -156,7 +156,7 @@ public: NS_DECL_NSITIMERCALLBACK NS_DECL_NSIPROPERTIES - RasterImage(); + RasterImage(imgStatusTracker* aStatusTracker = nsnull); virtual ~RasterImage(); // C++-only version of imgIContainer::GetType, for convenience diff --git a/modules/libpr0n/src/imgRequest.cpp b/modules/libpr0n/src/imgRequest.cpp index 731b00277187..37347cb5a0b8 100644 --- a/modules/libpr0n/src/imgRequest.cpp +++ b/modules/libpr0n/src/imgRequest.cpp @@ -204,10 +204,11 @@ nsresult imgRequest::Init(nsIURI *aURI, mProperties = do_CreateInstance("@mozilla.org/properties;1"); + mStatusTracker = new imgStatusTracker(nsnull); + // XXXdholbert For SVG support, this mImage-construction will need to happen // later -- *after* we know image mimetype. - nsCOMPtr comImg = do_CreateInstance("@mozilla.org/image/rasterimage;1"); - mImage = static_cast(comImg.get()); + mImage = new RasterImage(mStatusTracker.forget()); mURI = aURI; mKeyURI = aKeyURI; diff --git a/modules/libpr0n/src/imgRequest.h b/modules/libpr0n/src/imgRequest.h index bf89781370fb..a07ef8dcdc08 100644 --- a/modules/libpr0n/src/imgRequest.h +++ b/modules/libpr0n/src/imgRequest.h @@ -59,6 +59,7 @@ #include "nsWeakReference.h" #include "ImageErrors.h" #include "imgIRequest.h" +#include "imgStatusTracker.h" #include "nsIAsyncVerifyRedirectCallback.h" class imgCacheValidator; @@ -195,6 +196,8 @@ private: // The URI we are keyed on in the cache. nsCOMPtr mKeyURI; nsCOMPtr mPrincipal; + // Status-tracker -- transferred to mImage, when it gets instantiated + nsAutoPtr mStatusTracker; nsRefPtr mImage; nsCOMPtr mProperties; nsCOMPtr mSecurityInfo; diff --git a/modules/libpr0n/src/imgStatusTracker.cpp b/modules/libpr0n/src/imgStatusTracker.cpp index 4bbfbd26e588..3e9d110cd02e 100644 --- a/modules/libpr0n/src/imgStatusTracker.cpp +++ b/modules/libpr0n/src/imgStatusTracker.cpp @@ -75,6 +75,14 @@ imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther) // called. {} +void +imgStatusTracker::SetImage(Image* aImage) +{ + NS_ABORT_IF_FALSE(aImage, "Setting null image"); + NS_ABORT_IF_FALSE(!mImage, "Setting image when we already have one"); + mImage = aImage; +} + PRBool imgStatusTracker::IsLoading() const { diff --git a/modules/libpr0n/src/imgStatusTracker.h b/modules/libpr0n/src/imgStatusTracker.h index b7d50631acdd..fb631041259d 100644 --- a/modules/libpr0n/src/imgStatusTracker.h +++ b/modules/libpr0n/src/imgStatusTracker.h @@ -87,6 +87,12 @@ public: imgStatusTracker(mozilla::imagelib::Image* aImage); imgStatusTracker(const imgStatusTracker& aOther); + // Image-setter, for imgStatusTrackers created by imgRequest::Init, which + // are created before their Image is created. This method should only + // be called once, and only on an imgStatusTracker that was initialized + // without an image. + void SetImage(mozilla::imagelib::Image* aImage); + // Schedule an asynchronous "replaying" of all the notifications that would // have to happen to put us in the current state. // We will also take note of any notifications that happen between the time