Merge backout.
authorEdward Lee <edilee@mozilla.com>
Fri, 13 Aug 2010 21:52:38 -0700
changeset 50559 17f4064c1d23e04e8ee7be642e436a80a5fa3d6e
parent 50558 c14d91f2d939dd44580ac0e79802c9c5b029dd1d (current diff)
parent 50557 eccba2835f019af8110fe9127712aa83e04ad5b7 (diff)
child 50582 b71518936b4f23784d8aeeed3113fd0fb099ac47
push id15073
push useredward.lee@engineering.uiuc.edu
push dateSat, 14 Aug 2010 04:53:00 +0000
treeherdermozilla-central@17f4064c1d23 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0b4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge backout.
browser/base/content/tabview/ui.js
modules/libpr0n/decoders/icon/nsIconDecoder.cpp
modules/libpr0n/decoders/icon/nsIconDecoder.h
modules/libpr0n/src/imgContainer.cpp
modules/libpr0n/src/imgContainer.h
modules/libpr0n/src/imgDiscardTracker.cpp
modules/libpr0n/src/imgDiscardTracker.h
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -151,17 +151,17 @@ nsImageLoadingContent::~nsImageLoadingCo
   PR_END_MACRO
 
 
 /*
  * imgIContainerObserver impl
  */
 NS_IMETHODIMP
 nsImageLoadingContent::FrameChanged(imgIContainer* aContainer,
-                                    nsIntRect* aDirtyRect)
+                                    const nsIntRect* aDirtyRect)
 {
   LOOP_OVER_OBSERVERS(FrameChanged(aContainer, aDirtyRect));
   return NS_OK;
 }
             
 /*
  * imgIDecoderObserver impl
  */
--- a/content/base/src/nsStubImageDecoderObserver.cpp
+++ b/content/base/src/nsStubImageDecoderObserver.cpp
@@ -103,12 +103,12 @@ nsStubImageDecoderObserver::OnStopReques
 NS_IMETHODIMP 
 nsStubImageDecoderObserver::OnDiscard(imgIRequest *aRequest)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStubImageDecoderObserver::FrameChanged(imgIContainer *aContainer,
-                                         nsIntRect * aDirtyRect)
+                                         const nsIntRect *aDirtyRect)
 {
     return NS_OK;
 }
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -5332,17 +5332,18 @@ public:
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual PRInt32 IntrinsicState() const;
 
   // imgIDecoderObserver
   NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
                           const PRUnichar *statusArg);
   // imgIContainerObserver
-  NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *aDirtyRect);
   // imgIContainerObserver
   NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
                               imgIContainer *aContainer);
 
   void MaybeLoadSVGImage();
 
   virtual nsXPCClassInfo* GetClassInfo();
 private:
@@ -5601,20 +5602,20 @@ nsSVGFEImageElement::OnStopDecode(imgIRe
   nsresult rv =
     nsImageLoadingContent::OnStopDecode(aRequest, status, statusArg);
   Invalidate();
   return rv;
 }
 
 NS_IMETHODIMP
 nsSVGFEImageElement::FrameChanged(imgIContainer *aContainer,
-                                  nsIntRect *dirtyRect)
+                                  const nsIntRect *aDirtyRect)
 {
   nsresult rv =
-    nsImageLoadingContent::FrameChanged(aContainer, dirtyRect);
+    nsImageLoadingContent::FrameChanged(aContainer, aDirtyRect);
   Invalidate();
   return rv;
 }
 
 NS_IMETHODIMP
 nsSVGFEImageElement::OnStartContainer(imgIRequest *aRequest,
                                       imgIContainer *aContainer)
 {
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -621,22 +621,22 @@ protected:
     GLuint mOffscreenStencilRB;
 
     // this should just be a std::bitset, but that ended up breaking
     // MacOS X builds; see bug 584919.  We can replace this with one
     // later on.
     template<size_t setlen>
     struct ExtensionBitset {
         ExtensionBitset() {
-            for (int i = 0; i < setlen; ++i)
+            for (size_t i = 0; i < setlen; ++i)
                 values[i] = false;
         }
 
-        bool& operator[](const int index) {
-            NS_ASSERTION(index >= 0 && index < setlen, "out of range");
+        bool& operator[](size_t index) {
+            NS_ASSERTION(index < setlen, "out of range");
             return values[index];
         }
 
         bool values[setlen];
     };
     ExtensionBitset<Extensions_Max> mAvailableExtensions;
 
     // Clear to transparent black, with 0 depth and stencil,
--- a/layout/base/nsImageLoader.cpp
+++ b/layout/base/nsImageLoader.cpp
@@ -191,27 +191,27 @@ NS_IMETHODIMP nsImageLoader::OnStopReque
   }
   if (mActions & ACTION_REDRAW_ON_LOAD) {
     DoRedraw(nsnull);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsImageLoader::FrameChanged(imgIContainer *aContainer,
-                                          nsIntRect *dirtyRect)
+                                          const nsIntRect *aDirtyRect)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
   if (!mRequest) {
     // We're in the middle of a paint anyway
     return NS_OK;
   }
   
-  nsRect r = dirtyRect->ToAppUnits(nsPresContext::AppUnitsPerCSSPixel());
+  nsRect r = aDirtyRect->ToAppUnits(nsPresContext::AppUnitsPerCSSPixel());
 
   DoRedraw(&r);
 
   return NS_OK;
 }
 
 void
 nsImageLoader::DoReflow()
--- a/layout/base/nsImageLoader.h
+++ b/layout/base/nsImageLoader.h
@@ -86,17 +86,18 @@ public:
   NS_IMETHOD OnStopRequest(imgIRequest *aRequest, PRBool aLastPart);
   // Do not override OnDataAvailable since background images are not
   // displayed incrementally; they are displayed after the entire image
   // has been loaded.
   // Note: Images referenced by the <img> element are displayed
   // incrementally in nsImageFrame.cpp.
 
   // imgIContainerObserver (override nsStubImageDecoderObserver)
-  NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *aDirtyRect);
 
   void Destroy();
 
   imgIRequest *GetRequest() { return mRequest; }
   nsImageLoader *GetNextLoader() { return mNextLoader; }
 
 private:
   nsresult Load(imgIRequest *aImage);
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -71,17 +71,18 @@ public:
   NS_DECL_ISUPPORTS
   // imgIDecoderObserver (override nsStubImageDecoderObserver)
   NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
   NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
                              const nsIntRect *aRect);
   NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
                           const PRUnichar *statusArg);
   // imgIContainerObserver (override nsStubImageDecoderObserver)
-  NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *dirtyRect);
 
   void SetFrame(nsBulletFrame *frame) { mFrame = frame; }
 
 private:
   nsBulletFrame *mFrame;
 };
 
 NS_IMPL_FRAMEARENA_HELPERS(nsBulletFrame)
@@ -1499,17 +1500,17 @@ NS_IMETHODIMP nsBulletFrame::OnStopDecod
     }
   }
 #endif
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIContainer *aContainer,
-                                          nsIntRect *aDirtyRect)
+                                          const nsIntRect *aDirtyRect)
 {
   // Invalidate the entire content area. Maybe it's not optimal but it's simple and
   // always correct.
   Invalidate(nsRect(0, 0, mRect.width, mRect.height));
 
   return NS_OK;
 }
 
@@ -1576,15 +1577,15 @@ NS_IMETHODIMP nsBulletListener::OnStopDe
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
   
   return mFrame->OnStopDecode(aRequest, status, statusArg);
 }
 
 NS_IMETHODIMP nsBulletListener::FrameChanged(imgIContainer *aContainer,
-                                             nsIntRect *dirtyRect)
+                                             const nsIntRect *aDirtyRect)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
-  return mFrame->FrameChanged(aContainer, dirtyRect);
+  return mFrame->FrameChanged(aContainer, aDirtyRect);
 }
--- a/layout/generic/nsBulletFrame.h
+++ b/layout/generic/nsBulletFrame.h
@@ -83,17 +83,17 @@ public:
   NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
   NS_IMETHOD OnDataAvailable(imgIRequest *aRequest,
                              PRBool aCurrentFrame,
                              const nsIntRect *aRect);
   NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
                           nsresult aStatus,
                           const PRUnichar *aStatusArg);
   NS_IMETHOD FrameChanged(imgIContainer *aContainer,
-                          nsIntRect *aDirtyRect);
+                          const nsIntRect *aDirtyRect);
 
   /* get list item text, without '.' */
   static PRBool AppendCounterText(PRInt32 aListStyleType,
                                   PRInt32 aOrdinal,
                                   nsString& aResult);
 
   /* get list item text, with '.' */
   PRBool GetListItemText(const nsStyleList& aStyleList,
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -604,17 +604,18 @@ nsImageFrame::OnStopDecode(imgIRequest *
       }
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect)
+nsImageFrame::FrameChanged(imgIContainer *aContainer,
+                           const nsIntRect *aDirtyRect)
 {
   if (!GetStyleVisibility()->IsVisible()) {
     return NS_OK;
   }
 
   if (IsPendingLoad(aContainer)) {
     // We don't care about it
     return NS_OK;
@@ -1873,17 +1874,17 @@ nsImageFrame::IconLoad::OnStopRequest(im
 NS_IMETHODIMP
 nsImageFrame::IconLoad::OnDiscard(imgIRequest *aRequest)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsImageFrame::IconLoad::FrameChanged(imgIContainer *aContainer,
-                                     nsIntRect * aDirtyRect)
+                                     const nsIntRect *aDirtyRect)
 {
   nsTObserverArray<nsImageFrame*>::ForwardIterator iter(mIconObservers);
   nsImageFrame *frame;
   while (iter.HasMore()) {
     frame = iter.GetNext();
     frame->Invalidate(frame->GetRect());
   }
 
@@ -1928,22 +1929,22 @@ NS_IMETHODIMP nsImageListener::OnStopDec
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
   return mFrame->OnStopDecode(aRequest, status, statusArg);
 }
 
 NS_IMETHODIMP nsImageListener::FrameChanged(imgIContainer *aContainer,
-                                            nsIntRect * dirtyRect)
+                                            const nsIntRect *aDirtyRect)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
-  return mFrame->FrameChanged(aContainer, dirtyRect);
+  return mFrame->FrameChanged(aContainer, aDirtyRect);
 }
 
 static PRBool
 IsInAutoWidthTableCellForQuirk(nsIFrame *aFrame)
 {
   if (eCompatibility_NavQuirks != aFrame->PresContext()->CompatibilityMode())
     return PR_FALSE;
   // Check if the parent of the closest nsBlockFrame has auto width.
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -74,17 +74,18 @@ public:
   NS_DECL_ISUPPORTS
   // imgIDecoderObserver (override nsStubImageDecoderObserver)
   NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
   NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
                              const nsIntRect *aRect);
   NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
                           const PRUnichar *statusArg);
   // imgIContainerObserver (override nsStubImageDecoderObserver)
-  NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *dirtyRect);
 
   void SetFrame(nsImageFrame *frame) { mFrame = frame; }
 
 private:
   nsImageFrame *mFrame;
 };
 
 #define IMAGE_SIZECONSTRAINED       NS_FRAME_STATE_BIT(20)
@@ -221,17 +222,18 @@ protected:
 protected:
   friend class nsImageListener;
   nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
   nsresult OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
                            const nsIntRect *rect);
   nsresult OnStopDecode(imgIRequest *aRequest,
                         nsresult aStatus,
                         const PRUnichar *aStatusArg);
-  nsresult FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect);
+  nsresult FrameChanged(imgIContainer *aContainer,
+                        const nsIntRect *aDirtyRect);
 
 private:
   // random helpers
   inline void SpecToURI(const nsAString& aSpec, nsIIOService *aIOService,
                         nsIURI **aURI);
 
   inline void GetLoadGroup(nsPresContext *aPresContext,
                            nsILoadGroup **aLoadGroup);
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -259,17 +259,17 @@ random == 99850-1b.html 99850-1-ref.html
 == 280708-1a.html 280708-1-ref.html
 == 280708-1b.html 280708-1-ref.html
 == 281241-1.html 281241-1-ref.html
 == 281241-2.xhtml 281241-1-ref.html
 == 283686-1.html about:blank
 == 283686-2.html 283686-2-ref.html
 == 283686-3.html about:blank
 == 289384-1.xhtml 289384-ref.xhtml
-fails-if(gtk2Widget) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 409329 for the non-Mac failures
+fails-if(gtk2Widget||d2d) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 409329 for the non-Mac failures
 asserts(1) == 290129-1.html 290129-1-ref.html # bug 315549/460637
 == 291078-1.html 291078-1-ref.html
 == 291078-2.html 291078-2-ref.html
 == 291262-1.html 291262-1-ref.html
 == 294306-1.html 294306-1a-ref.html
 != 294306-1.html 294306-1b-ref.html
 == 296361-1.html 296361-ref.html
 == 296904-1.html 296904-1-ref.html
@@ -643,18 +643,18 @@ fails == 374927-1.html 374927-1-ref.html
 == 378937-1.html 378937-1-ref.html
 == 379178-xhtml.xhtml 379178-xhtml-ref.xhtml
 == 379178-html.html 379178-html-ref.html
 == 379178-svg.svg 379178-svg-ref.svg
 == 379316-1.html 379316-1-ref.html
 random-if(cocoaWidget) == 379316-2.html 379316-2-ref.html # bug 379786
 == 379328-1.html 379328-1-ref.html
 == 379349-1a.xhtml 379349-1-ref.xhtml
-== 379349-1b.xhtml 379349-1-ref.xhtml
-== 379349-1c.xhtml 379349-1-ref.xhtml
+fails-if(d2d) == 379349-1b.xhtml 379349-1-ref.xhtml # bug 578116
+fails-if(d2d) == 379349-1c.xhtml 379349-1-ref.xhtml # bug 578116
 == 379349-2a.xhtml 379349-2-ref.xhtml
 == 379349-2b.xhtml 379349-2-ref.xhtml
 == 379349-3a.xhtml 379349-3-ref.xhtml
 == 379349-3b.xhtml 379349-3-ref.xhtml
 == 379361-1.html 379361-1-ref.html
 == 379361-2.html 379361-2-ref.html
 == 379361-3.html 379361-3-ref.html
 == 379461-1.xhtml 379461-1.html
@@ -1265,18 +1265,18 @@ fails == 472020-2.xul 472020-2-ref.xul
 == 481024-1b.html 481024-1-ref.html
 == 481024-1c.html 481024-1-ref.html
 == 481024-1d.html 481024-1-ref.html
 == 481024-1e.html 481024-1-ref.html
 != 481948-1.html 481948-1-ref.html
 != 481948-2.html 481948-2-ref.html
 random-if(winWidget) fails-if(gtk2Widget) == 481948-3.html 481948-3-ref.html # questionable test, see bug 488364
 == 482398-1.html 482398-1-ref.html
-== 482592-1a.xhtml 482592-1-ref.html
-== 482592-1b.xhtml 482592-1-ref.html
+random-if(d2d) == 482592-1a.xhtml 482592-1-ref.html # bug 586771
+random-if(d2d) == 482592-1b.xhtml 482592-1-ref.html # bug 586771
 == 482659-1a.html 482659-1-ref.html
 == 482659-1b.html 482659-1-ref.html
 == 482659-1c.html 482659-1-ref.html
 == 482659-1d.html 482659-1-ref.html
 == 483565.xul 483565-ref.xul
 == 484256-1.html 484256-1-ref.html
 == 484256-2.html 484256-1-ref.html
 == 485012-1.html 485012-1-ref.html
@@ -1380,17 +1380,17 @@ HTTP(..) == 518172-2b.html 518172-b-ref.
 == 521525-1.html 521525-1-ref.html
 == 521525-2.html 521525-2-ref.html
 == 521539-1.html 521539-1-ref.html
 == 521542-1.xhtml 521542-1-ref.xhtml
 == 521602.html 521602-ref.html
 == 521685-1.html 521685-1-ref.html
 == 522632-1.html 522632-1-ref.html
 == 523096-1.html 523096-1-ref.html
-== 523468-1.html 523468-1-ref.html
+random-if(d2d) == 523468-1.html 523468-1-ref.html
 == 524175-1.html 524175-1-ref.html
 == 526463-1.html 526463-1-ref.html
 == 527464-1.html 527464-ref.html
 == 528038-1a.html 528038-1-ref.html
 == 528038-1b.html 528038-1-ref.html
 == 528038-1c.html 528038-1-ref.html
 == 528038-1d.html 528038-1-ref.html
 == 528038-1e.html 528038-1-ref.html
@@ -1422,17 +1422,17 @@ random-if(!haveTestPlugin) == 541406-1.h
 == 545049-1.html 545049-1-ref.html
 == 546033-1.html 546033-1-ref.html
 random-if(!haveTestPlugin) == 546071-1.html 546071-1-ref.html
 == 549184-1.html 549184-1-ref.html
 == 550716-1.html 550716-1-ref.html
 == 551463-1.html 551463-1-ref.html
 == 551699-1.html 551699-1-ref.html
 == 552334-1.html 552334-1-ref.html
-== 555388-1.html 555388-1-ref.html
+random-if(d2d) == 555388-1.html 555388-1-ref.html
 == 556661-1.html 556661-1-ref.html
 == 557736-1.html 557736-1-ref.html
 == 559284-1.html 559284-1-ref.html
 == 560455-1.xul 560455-1-ref.xul
 == 561981-1.html 561981-1-ref.html
 == 561981-2.html 561981-2-ref.html
 == 561981-3.html 561981-3-ref.html
 == 561981-4.html 561981-4-ref.html
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -11,22 +11,22 @@
 == linear-diagonal-4a.html linear-diagonal-4-ref.html
 == linear-diagonal-4b.html linear-diagonal-4-ref.html
 == linear-diagonal-5a.html linear-diagonal-5-ref.html
 == linear-diagonal-6a.html linear-diagonal-6-ref.html
 == linear-diagonal-7a.html linear-diagonal-7-ref.html
 == linear-diagonal-8a.html linear-diagonal-8-ref.html
 == linear-position-1a.html linear-position-1-ref.html
 == linear-repeat-1a.html linear-repeat-1-ref.html
-== linear-repeat-1b.html linear-repeat-1-ref.html
+fails-if(d2d) == linear-repeat-1b.html linear-repeat-1-ref.html # bug 582236
 == linear-repeat-1c.html linear-repeat-1-ref.html
-== linear-repeat-1d.html linear-repeat-1-ref.html
+fails-if(d2d) == linear-repeat-1d.html linear-repeat-1-ref.html # bug 582236
 == linear-repeat-1e.html linear-repeat-1-ref.html
-== linear-repeat-1f.html linear-repeat-1-ref.html
-== linear-repeat-1g.html linear-repeat-1-ref.html
+fails-if(d2d) == linear-repeat-1f.html linear-repeat-1-ref.html # bug 582236
+fails-if(d2d) == linear-repeat-1g.html linear-repeat-1-ref.html # bug 582236
 == linear-size-1a.html linear-size-1-ref.html
 == linear-stops-1a.html linear-stops-1-ref.html
 == linear-stops-1b.html linear-stops-1-ref.html
 == linear-stops-1c.html linear-stops-1-ref.html
 == linear-stops-1d.html linear-stops-1-ref.html
 == linear-stops-1e.html linear-stops-1-ref.html
 == linear-stops-1f.html linear-stops-1-ref.html
 == linear-vertical-1a.html linear-vertical-1-ref.html
@@ -34,55 +34,55 @@
 == linear-vertical-1c.html linear-vertical-1-ref.html
 == linear-vertical-1d.html linear-vertical-1-ref.html
 == linear-viewport.html linear-viewport-ref.html
 == linear-zero-length-1a.html linear-zero-length-1-ref.html
 == linear-zero-length-1b.html linear-zero-length-1-ref.html
 == linear-zero-length-1c.html linear-zero-length-1-ref.html
 == nostops.html about:blank
 == onestop.html about:blank
-== radial-1a.html radial-1-ref.html
+random-if(d2d) == radial-1a.html radial-1-ref.html
 == radial-2a.html radial-2-ref.html
 == radial-2b.html radial-2-ref.html
 == radial-position-1a.html radial-position-1-ref.html
 == radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html
 == radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html
 == radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html
 == radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html
 == radial-size-1a.html radial-size-1-ref.html
 == radial-zero-length-1a.html radial-zero-length-1-ref.html
 == radial-zero-length-1b.html radial-zero-length-1-ref.html
 == radial-zero-length-1c.html radial-zero-length-1-ref.html
 == radial-zero-length-1d.html radial-zero-length-1-ref.html
 == radial-zero-length-1e.html radial-zero-length-1-ref.html
 == radial-zero-length-1f.html radial-zero-length-1-ref.html
-== repeating-linear-1a.html repeating-linear-1-ref.html
-== repeating-linear-1b.html repeating-linear-1-ref.html
+fails-if(d2d) == repeating-linear-1a.html repeating-linear-1-ref.html
+fails-if(d2d) == repeating-linear-1b.html repeating-linear-1-ref.html
 == repeating-linear-2a.html repeating-linear-2-ref.html
 == repeating-radial-1a.html repeating-radial-1-ref.html
 == repeating-radial-1b.html repeating-radial-1-ref.html
 == repeating-radial-2a.html repeating-radial-2-ref.html
 == twostops-1a.html twostops-1-ref.html
 == twostops-1b.html twostops-1-ref.html
-fails == twostops-1c.html twostops-1-ref.html # bug 524173
+fails-if(!d2d) == twostops-1c.html twostops-1-ref.html # bug 524173
 == twostops-1d.html twostops-1-ref.html
-fails-if(!cocoaWidget) == twostops-1e.html twostops-1-ref.html # bug 524173
+fails-if(!cocoaWidget&&!d2d) == twostops-1e.html twostops-1-ref.html # bug 524173
 
 # from http://www.xanthir.com/:4bhipd by way of http://a-ja.net/newgrad.html
 == aja-linear-1a.html aja-linear-1-ref.html
-fails == aja-linear-1b.html aja-linear-1-ref.html # bug 526694
+fails-if(!d2d) == aja-linear-1b.html aja-linear-1-ref.html # bug 526694
 == aja-linear-1c.html aja-linear-1-ref.html
 == aja-linear-1d.html aja-linear-1-ref.html
 == aja-linear-1e.html aja-linear-1-ref.html
 == aja-linear-1f.html aja-linear-1-ref.html
 == aja-linear-1g.html aja-linear-1-ref.html
 == aja-linear-2a.html aja-linear-2-ref.html
 == aja-linear-2b.html aja-linear-2-ref.html
 fails == aja-linear-2c.html aja-linear-2-ref.html # bug 522607
-fails == aja-linear-2d.html aja-linear-2-ref.html # bug 526694
+fails-if(!d2d) == aja-linear-2d.html aja-linear-2-ref.html # bug 526694
 == aja-linear-3a.html aja-linear-3-ref.html
 == aja-linear-3b.html aja-linear-3-ref.html
 == aja-linear-4a.html aja-linear-4-ref.html
 == aja-linear-4b.html aja-linear-4-ref.html
 == aja-linear-5a.html aja-linear-5-ref.html
 fails-if(/Mac\x20OS\x20X\x2010\.5/.test(http.oscpu)) == aja-linear-6a.html aja-linear-6-ref.html # bug 526708
 fails == aja-linear-6b.html aja-linear-6-ref.html # bug 522607
 == height-dependence-1.html height-dependence-1-ref.html
--- a/layout/reftests/first-letter/reftest.list
+++ b/layout/reftests/first-letter/reftest.list
@@ -18,17 +18,17 @@ fails == quote-1b.html quote-1-ref.html 
 fails == quote-1c.html quote-1-ref.html # bug 509685
 == quote-1c.html quote-1b.html
 fails == quote-1d.html quote-1-ref.html
 random == quote-1d.html quote-1b.html
 fails == quote-1e.html quote-1-ref.html # bug 509685
 == quote-1e.html quote-1b.html
 == quote-1f.html quote-1-ref.html
 fails == dynamic-1.html dynamic-1-ref.html # bug 8253
-== dynamic-2.html dynamic-2-ref.html
+random-if(d2d) == dynamic-2.html dynamic-2-ref.html
 == dynamic-3a.html dynamic-3-ref.html
 random == dynamic-3b.html dynamic-3-ref.html
 == 23605-1.html 23605-1-ref.html
 == 23605-2.html 23605-2-ref.html
 == 23605-3.html 23605-3-ref.html
 == 23605-4.html 23605-4-ref.html
 == 23605-5.html 23605-5-ref.html
 == 23605-6.html 23605-6-ref.html
--- a/layout/reftests/image-element/reftest.list
+++ b/layout/reftests/image-element/reftest.list
@@ -6,17 +6,17 @@
 == image-outside-document-invalidate.html about:blank
 == canvas-outside-document-invalidate-01.html about:blank
 == canvas-outside-document-invalidate-02.html about:blank
 == element-paint-simple.html element-paint-simple-ref.html
 == element-paint-repeated.html element-paint-repeated-ref.html
 == element-paint-recursion.html element-paint-recursion-ref.html
 HTTP(..) == element-paint-continuation.html element-paint-continuation-ref.html
 == element-paint-transform-01.html element-paint-transform-01-ref.html
-== element-paint-transform-02.html element-paint-transform-02-ref.html
+random-if(d2d) == element-paint-transform-02.html element-paint-transform-02-ref.html # bug 587133
 == element-paint-background-size-01.html element-paint-background-size-01-ref.html
 == element-paint-background-size-02.html element-paint-background-size-02-ref.html
 == element-paint-transform-repeated.html element-paint-transform-repeated-ref.html
 == element-paint-transform-03.html element-paint-transform-03-ref.html
 == element-paint-native-widget.html element-paint-native-widget-ref.html
 == element-paint-subimage-sampling-restriction.html about:blank
 == element-paint-clippath.html element-paint-clippath-ref.html
 == element-paint-sharpness-01a.html element-paint-sharpness-01b.html
--- a/layout/reftests/svg/filters/reftest.list
+++ b/layout/reftests/svg/filters/reftest.list
@@ -44,17 +44,17 @@
 == feTile-1.svg feTile-1-ref.svg
 == feTile-2.svg feTile-2-ref.svg
 
 # no tests for feSpecularLighting, feDiffuseLighting or feTurbulence
 
 == filter-clipped-rect-01.svg pass.svg
 == filter-filterRes-high-01.svg pass.svg
 == filter-filterRes-high-02.svg pass.svg
-== filter-filterRes-low-01.svg pass.svg
+random-if(d2d) == filter-filterRes-low-01.svg pass.svg
 == filter-inner-svg-01.svg pass.svg
 == filter-inner-svg-02.svg pass.svg
 == filter-inner-svg-03.svg pass.svg
 fails == filter-marked-line-01.svg pass.svg # bug 477704
 == filter-marked-line-02.svg pass.svg
 == filter-marked-line-03.svg pass.svg
 == filter-marked-line-04.svg pass.svg
 == filter-marked-line-05.svg pass.svg
--- a/layout/reftests/svg/smil/container/reftest.list
+++ b/layout/reftests/svg/smil/container/reftest.list
@@ -1,16 +1,16 @@
 # Tests related to SVG Animation (using SMIL), focusing on animation-sorting
 # to see which animation takes precedence (out of multiple animations on the
 # same attribute)
 
 random == enveloped-tree-1.xhtml enveloped-tree-1-ref.xhtml  # bug 470868
 == promoted-tree-1.xhtml promoted-tree-1-ref.xhtml
 random == moved-tree-1.xhtml moved-tree-1-ref.xhtml  # bug 470868
-random-if(cocoaWidget) == deferred-anim-1.xhtml deferred-anim-1-ref.xhtml # bug 470868
+random-if(cocoaWidget||d2d) == deferred-anim-1.xhtml deferred-anim-1-ref.xhtml # bug 470868, bug 585484
 == deferred-tree-1.xhtml deferred-tree-1-ref.xhtml
 == deferred-tree-2a.xhtml deferred-tree-2-ref.xhtml
 == deferred-tree-2b.xhtml deferred-tree-2-ref.xhtml
 == deferred-tree-3a.xhtml deferred-tree-3-ref.xhtml
 == deferred-tree-3b.xhtml deferred-tree-3-ref.xhtml
 == deferred-tree-3c.xhtml deferred-tree-3-ref.xhtml
 == deferred-tree-3d.xhtml deferred-tree-3-ref.xhtml
 # this will occasionally fail until we correctly clear animation effects from
--- a/layout/reftests/table-anonymous-boxes/reftest.list
+++ b/layout/reftests/table-anonymous-boxes/reftest.list
@@ -22,18 +22,18 @@ fails == 156888-1.html 156888-1-ref.html
 == 363326-1.html 363326-1-ref.html
 == 368932-1.html 368932-1-ref.html
 == 371054-1.html 371054-1-ref.html
 == 372641-1a.xhtml 372641-1-ref.xhtml
 == 372641-1b.xhtml 372641-1-ref.xhtml
 == 372641-1c.xhtml 372641-1-ref.xhtml
 == 372649-1.html 372649-1-ref.html
 == 373379-1.html 373379-1-ref.html
-== 394402-1a.html 394402-1-ref.html
-== 394402-1b.html 394402-1-ref.html
+random-if(d2d) == 394402-1a.html 394402-1-ref.html # bug 586833
+== 394402-1b.html 394402-1-ref.html # bug 586833
 == 398095-1.html 398095-1-ref.html
 == 407115-1.html 407115-1-ref.html
 == 443616-1a.xhtml 443616-1-ref.html
 == 443616-1b.html 443616-1-ref.html
 == 448111-1.html 448111-1-ref.html
 == infer-first-row.html 3x3-ref.html
 == infer-first-row-and-table.html 3x3-ref.html
 == infer-second-row.html 3x3-ref.html
--- a/layout/reftests/text-decoration/reftest.list
+++ b/layout/reftests/text-decoration/reftest.list
@@ -12,11 +12,11 @@ fails == underline-block-propagation-2-q
 != underline-block-standards.html underline-block-standards-notref.html
 == underline-inline-block-standards.html underline-inline-block-standards-ref.html
 != underline-inline-block-standards.html underline-inline-block-standards-notref.html
 == underline-table-caption-standards.html underline-table-caption-standards-ref.html
 != underline-table-caption-standards.html underline-table-caption-standards-notref.html
 == underline-table-cell-standards.html underline-table-cell-standards-ref.html
 != underline-table-cell-standards.html underline-table-cell-standards-notref.html
 fails == underline-block-propagation-standards.html underline-block-propagation-standards-ref.html # bug that decoration is drawn through non-text child (bug 428599)
-== underline-block-propagation-2-standards.html underline-block-propagation-2-standards-ref.html
+fails-if(d2d) == underline-block-propagation-2-standards.html underline-block-propagation-2-standards-ref.html # bug 585684
 == text-decoration-zorder-1-standards.html text-decoration-zorder-1-ref.html
 fails == text-decoration-zorder-1-quirks.html text-decoration-zorder-1-ref.html # bug 403524
--- a/layout/svg/base/src/nsSVGImageFrame.cpp
+++ b/layout/svg/base/src/nsSVGImageFrame.cpp
@@ -53,17 +53,18 @@ class nsSVGImageListener : public nsStub
 public:
   nsSVGImageListener(nsSVGImageFrame *aFrame);
 
   NS_DECL_ISUPPORTS
   // imgIDecoderObserver (override nsStubImageDecoderObserver)
   NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
                           const PRUnichar *statusArg);
   // imgIContainerObserver (override nsStubImageDecoderObserver)
-  NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *aDirtyRect);
   // imgIContainerObserver (override nsStubImageDecoderObserver)
   NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
                               imgIContainer *aContainer);
 
   void SetFrame(nsSVGImageFrame *frame) { mFrame = frame; }
 
 private:
   nsSVGImageFrame *mFrame;
@@ -397,17 +398,17 @@ NS_IMETHODIMP nsSVGImageListener::OnStop
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
   nsSVGUtils::UpdateGraphic(mFrame);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIContainer *aContainer,
-                                               nsIntRect * dirtyRect)
+                                               const nsIntRect *aDirtyRect)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
   nsSVGUtils::UpdateGraphic(mFrame);
   return NS_OK;
 }
 
--- a/layout/xul/base/src/nsImageBoxFrame.cpp
+++ b/layout/xul/base/src/nsImageBoxFrame.cpp
@@ -542,18 +542,18 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopDec
     PresContext()->PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
     FireImageDOMEvent(mContent, NS_LOAD_ERROR);
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIContainer *container,
-                                            nsIntRect *dirtyRect)
+NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIContainer *aContainer,
+                                            const nsIntRect *aDirtyRect)
 {
   nsBoxLayoutState state(PresContext());
   this->Redraw(state);
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS2(nsImageBoxListener, imgIDecoderObserver, imgIContainerObserver)
@@ -589,17 +589,17 @@ NS_IMETHODIMP nsImageBoxListener::OnStop
                                                const PRUnichar *statusArg)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
   return mFrame->OnStopDecode(request, status, statusArg);
 }
 
-NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIContainer *container,
-                                               nsIntRect *dirtyRect)
+NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIContainer *aContainer,
+                                               const nsIntRect *aDirtyRect)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
-  return mFrame->FrameChanged(container, dirtyRect);
+  return mFrame->FrameChanged(aContainer, aDirtyRect);
 }
 
--- a/layout/xul/base/src/nsImageBoxFrame.h
+++ b/layout/xul/base/src/nsImageBoxFrame.h
@@ -54,17 +54,18 @@ public:
 
   NS_DECL_ISUPPORTS
   // imgIDecoderObserver (override nsStubImageDecoderObserver)
   NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
   NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
   NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status,
                           const PRUnichar *statusArg);
   // imgIContainerObserver (override nsStubImageDecoderObserver)
-  NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *aDirtyRect);
 
   void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; }
 
 private:
   nsImageBoxFrame *mFrame;
 };
 
 class nsImageBoxFrame : public nsLeafBoxFrame
@@ -116,17 +117,18 @@ public:
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
   NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
   NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
   NS_IMETHOD OnStopDecode(imgIRequest *request,
                           nsresult status,
                           const PRUnichar *statusArg);
-  NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *aDirtyRect);
 
   virtual ~nsImageBoxFrame();
 
   void  PaintImage(nsIRenderingContext& aRenderingContext,
                    const nsRect& aDirtyRect,
                    nsPoint aPt, PRUint32 aFlags);
 
 protected:
--- a/layout/xul/base/src/tree/src/nsTreeImageListener.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeImageListener.cpp
@@ -67,17 +67,17 @@ NS_IMETHODIMP nsTreeImageListener::OnDat
                                                    PRBool aCurrentFrame,
                                                    const nsIntRect *aRect)
 {
   Invalidate();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsTreeImageListener::FrameChanged(imgIContainer *aContainer,
-                                                nsIntRect *dirtyRect)
+                                                const nsIntRect *aDirtyRect)
 {
   Invalidate();
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsTreeImageListener::AddCell(PRInt32 aIndex, nsITreeColumn* aCol)
--- a/layout/xul/base/src/tree/src/nsTreeImageListener.h
+++ b/layout/xul/base/src/tree/src/nsTreeImageListener.h
@@ -70,17 +70,18 @@ public:
   ~nsTreeImageListener();
 
   NS_DECL_ISUPPORTS
   // imgIDecoderObserver (override nsStubImageDecoderObserver)
   NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
   NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
                              const nsIntRect *aRect);
   // imgIContainerObserver (override nsStubImageDecoderObserver)
-  NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
+  NS_IMETHOD FrameChanged(imgIContainer *aContainer,
+                          const nsIntRect *aDirtyRect);
 
   NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol);
  
   friend class nsTreeBodyFrame;
 
 protected:
   void UnsuppressInvalidation() { mInvalidationSuppressed = PR_FALSE; }
   void Invalidate();
--- a/modules/libpr0n/build/nsImageModule.cpp
+++ b/modules/libpr0n/build/nsImageModule.cpp
@@ -46,41 +46,42 @@
 #define IMG_BUILD_jpeg 1
 #endif
 
 #include "nsIDeviceContext.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsXPCOMCID.h"
 #include "nsServiceManagerUtils.h"
 
-#include "imgContainer.h"
+#include "RasterImage.h"
 
 /* We end up pulling in windows.h because we eventually hit gfxWindowsSurface;
  * windows.h defines LoadImage, so we have to #undef it or imgLoader::LoadImage
  * gets changed.
  * This #undef needs to be in multiple places because we don't always pull
  * headers in in the same order.
  */
 #undef LoadImage
 
 #include "imgLoader.h"
 #include "imgRequest.h"
 #include "imgRequestProxy.h"
 #include "imgTools.h"
-#include "imgDiscardTracker.h"
+#include "DiscardTracker.h"
 
 #ifdef IMG_BUILD_DECODER_gif
 // gif
 #include "nsGIFDecoder2.h"
 #endif
 
 #ifdef IMG_BUILD_DECODER_bmp
 // bmp/ico
 #include "nsBMPDecoder.h"
 #include "nsICODecoder.h"
+#include "nsIconDecoder.h"
 #endif
 
 #ifdef IMG_BUILD_DECODER_png
 // png
 #include "nsPNGDecoder.h"
 #endif
 
 #ifdef IMG_BUILD_DECODER_jpeg
@@ -93,18 +94,23 @@
 #include "nsPNGEncoder.h"
 #endif
 #ifdef IMG_BUILD_ENCODER_jpeg
 // jpeg
 #include "nsJPEGEncoder.h"
 #endif
 
 // objects that just require generic constructors
+namespace mozilla {
+namespace imagelib {
+NS_GENERIC_FACTORY_CONSTRUCTOR(RasterImage)
+}
+}
+using namespace mozilla::imagelib;
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(imgContainer)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(imgLoader, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy)
 NS_GENERIC_FACTORY_CONSTRUCTOR(imgTools)
 
 #ifdef IMG_BUILD_DECODER_gif
 // gif
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIFDecoder2)
 #endif
@@ -117,101 +123,105 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGDec
 // jpeg
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGEncoder)
 #endif
 
 #ifdef IMG_BUILD_DECODER_bmp
 // bmp
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsICODecoder)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBMPDecoder)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconDecoder)
 #endif
 
 #ifdef IMG_BUILD_DECODER_png
 // png
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGDecoder)
 #endif
 #ifdef IMG_BUILD_ENCODER_png
 // png
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGEncoder)
 #endif
 
 NS_DEFINE_NAMED_CID(NS_IMGLOADER_CID);
-NS_DEFINE_NAMED_CID(NS_IMGCONTAINER_CID);
 NS_DEFINE_NAMED_CID(NS_IMGREQUESTPROXY_CID);
 NS_DEFINE_NAMED_CID(NS_IMGTOOLS_CID);
+NS_DEFINE_NAMED_CID(NS_RASTERIMAGE_CID);
 #ifdef IMG_BUILD_DECODER_gif
 NS_DEFINE_NAMED_CID(NS_GIFDECODER2_CID);
 #endif
 #ifdef IMG_BUILD_DECODER_jpeg
 NS_DEFINE_NAMED_CID(NS_JPEGDECODER_CID);
 #endif
 #ifdef IMG_BUILD_ENCODER_jpeg
 NS_DEFINE_NAMED_CID(NS_JPEGENCODER_CID);
 #endif
 #ifdef IMG_BUILD_DECODER_bmp
 NS_DEFINE_NAMED_CID(NS_ICODECODER_CID);
 NS_DEFINE_NAMED_CID(NS_BMPDECODER_CID);
+NS_DEFINE_NAMED_CID(NS_ICONDECODER_CID);
 #endif
 #ifdef IMG_BUILD_DECODER_png
 NS_DEFINE_NAMED_CID(NS_PNGDECODER_CID);
 #endif
 #ifdef IMG_BUILD_ENCODER_png
 NS_DEFINE_NAMED_CID(NS_PNGENCODER_CID);
 #endif
 
 
 static const mozilla::Module::CIDEntry kImageCIDs[] = {
   { &kNS_IMGLOADER_CID, false, NULL, imgLoaderConstructor, },
-  { &kNS_IMGCONTAINER_CID, false, NULL, imgContainerConstructor, },
   { &kNS_IMGREQUESTPROXY_CID, false, NULL, imgRequestProxyConstructor, },
   { &kNS_IMGTOOLS_CID, false, NULL, imgToolsConstructor, },
+  { &kNS_RASTERIMAGE_CID, false, NULL, RasterImageConstructor, },
 #ifdef IMG_BUILD_DECODER_gif
   { &kNS_GIFDECODER2_CID, false, NULL, nsGIFDecoder2Constructor, },
 #endif
 #ifdef IMG_BUILD_DECODER_jpeg
   { &kNS_JPEGDECODER_CID, false, NULL, nsJPEGDecoderConstructor, },
 #endif
 #ifdef IMG_BUILD_ENCODER_jpeg
   { &kNS_JPEGENCODER_CID, false, NULL, nsJPEGEncoderConstructor, },
 #endif
 #ifdef IMG_BUILD_DECODER_bmp
   { &kNS_ICODECODER_CID, false, NULL, nsICODecoderConstructor, },
   { &kNS_BMPDECODER_CID, false, NULL, nsBMPDecoderConstructor, },
+  { &kNS_ICONDECODER_CID, false, NULL, nsIconDecoderConstructor, },
 #endif
 #ifdef IMG_BUILD_DECODER_png
   { &kNS_PNGDECODER_CID, false, NULL, nsPNGDecoderConstructor, },
 #endif
 #ifdef IMG_BUILD_ENCODER_png
   { &kNS_PNGENCODER_CID, false, NULL, nsPNGEncoderConstructor, },
 #endif
   { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kImageContracts[] = {
   { "@mozilla.org/image/cache;1", &kNS_IMGLOADER_CID },
-  { "@mozilla.org/image/container;3", &kNS_IMGCONTAINER_CID },
   { "@mozilla.org/image/loader;1", &kNS_IMGLOADER_CID },
   { "@mozilla.org/image/request;1", &kNS_IMGREQUESTPROXY_CID },
   { "@mozilla.org/image/tools;1", &kNS_IMGTOOLS_CID },
+  { "@mozilla.org/image/rasterimage;1", &kNS_RASTERIMAGE_CID },
 #ifdef IMG_BUILD_DECODER_gif
   { "@mozilla.org/image/decoder;3?type=image/gif", &kNS_GIFDECODER2_CID },
 #endif
 #ifdef IMG_BUILD_DECODER_jpeg
   { "@mozilla.org/image/decoder;3?type=image/jpeg", &kNS_JPEGDECODER_CID },
   { "@mozilla.org/image/decoder;3?type=image/pjpeg", &kNS_JPEGDECODER_CID },
   { "@mozilla.org/image/decoder;3?type=image/jpg", &kNS_JPEGDECODER_CID },
 #endif
 #ifdef IMG_BUILD_ENCODER_jpeg
   { "@mozilla.org/image/encoder;2?type=image/jpeg", &kNS_JPEGENCODER_CID },
 #endif
 #ifdef IMG_BUILD_DECODER_bmp
   { "@mozilla.org/image/decoder;3?type=image/x-icon", &kNS_ICODECODER_CID },
   { "@mozilla.org/image/decoder;3?type=image/vnd.microsoft.icon", &kNS_ICODECODER_CID },
   { "@mozilla.org/image/decoder;3?type=image/bmp", &kNS_BMPDECODER_CID },
   { "@mozilla.org/image/decoder;3?type=image/x-ms-bmp", &kNS_BMPDECODER_CID },
+  { "@mozilla.org/image/decoder;3?type=image/icon", &kNS_ICONDECODER_CID },
 #endif
 #ifdef IMG_BUILD_DECODER_png
   { "@mozilla.org/image/decoder;3?type=image/png", &kNS_PNGDECODER_CID },
   { "@mozilla.org/image/decoder;3?type=image/x-png", &kNS_PNGDECODER_CID },
 #endif
 #ifdef IMG_BUILD_ENCODER_png
   { "@mozilla.org/image/encoder;2?type=image/png", &kNS_PNGENCODER_CID },
 #endif
@@ -227,16 +237,17 @@ static const mozilla::Module::CategoryEn
   { "Gecko-Content-Viewers", "image/pjpeg", "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", "image/jpg", "@mozilla.org/content/document-loader-factory;1" },
 #endif
 #ifdef IMG_BUILD_DECODER_bmp
   { "Gecko-Content-Viewers", "image/x-icon", "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", "image/vnd.microsoft.icon", "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", "image/bmp", "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", "image/x-ms-bmp", "@mozilla.org/content/document-loader-factory;1" },
+  { "Gecko-Content-Viewers", "image/icon", "@mozilla.org/content/document-loader-factory;1" },
 #endif
 #ifdef IMG_BUILD_DECODER_png
   { "Gecko-Content-Viewers", "image/png", "@mozilla.org/content/document-loader-factory;1" },
   { "Gecko-Content-Viewers", "image/x-png", "@mozilla.org/content/document-loader-factory;1" },
 #endif
   { "content-sniffing-services", "@mozilla.org/image/loader;1", "@mozilla.org/image/loader;1" },
   { NULL }
 };
@@ -253,17 +264,17 @@ imglib_Initialize()
   imgLoader::InitCache();
   return NS_OK;
 }
 
 static void
 imglib_Shutdown()
 {
   imgLoader::Shutdown();
-  imgDiscardTracker::Shutdown();
+  mozilla::imagelib::DiscardTracker::Shutdown();
 }
 
 static const mozilla::Module kImageModule = {
   mozilla::Module::kVersion,
   kImageCIDs,
   kImageContracts,
   kImageCategories,
   NULL,
--- a/modules/libpr0n/decoders/bmp/Makefile.in
+++ b/modules/libpr0n/decoders/bmp/Makefile.in
@@ -45,11 +45,14 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE		= imgbmp
 LIBRARY_NAME	= imgbmp_s
 FORCE_STATIC_LIB = 1
 MODULE_NAME	= nsBMPModule
 LIBXUL_LIBRARY  = 1
 
 
-CPPSRCS        = nsBMPDecoder.cpp nsICODecoder.cpp
+CPPSRCS        = nsBMPDecoder.cpp nsICODecoder.cpp nsIconDecoder.cpp
+
+# ns[BMP,ICO,Icon]Decoder.cpp all include RasterImage.h
+LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/
 
 include $(topsrcdir)/config/rules.mk
--- a/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp
+++ b/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp
@@ -42,22 +42,25 @@
  * Big-Endian machines like the PowerPC. */
 
 #include <stdlib.h>
 
 #include "nsBMPDecoder.h"
 
 #include "nsIInputStream.h"
 #include "nsIComponentManager.h"
+#include "RasterImage.h"
 #include "imgIContainerObserver.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 
 #include "prlog.h"
 
+using namespace mozilla::imagelib;
+
 #ifdef PR_LOGGING
 PRLogModuleInfo *gBMPLog = PR_NewLogModule("BMPDecoder");
 #endif
 
 // Convert from row (1..height) to absolute line (0..height-1)
 #define LINE(row) ((mBIH.height < 0) ? (-mBIH.height - (row)) : ((row) - 1))
 #define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col)
 
@@ -81,18 +84,22 @@ nsBMPDecoder::~nsBMPDecoder()
   if (mRow)
       free(mRow);
 }
 
 NS_IMETHODIMP nsBMPDecoder::Init(imgIContainer *aImage,
                                  imgIDecoderObserver *aObserver,
                                  PRUint32 aFlags)
 {
+    NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
+                      "wrong type of imgIContainer for decoding into");
+
     PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Init(%p)\n", aImage));
-    mImage = aImage;
+
+    mImage = static_cast<RasterImage*>(aImage);
     mObserver = aObserver;
     mFlags = aFlags;
 
     // Fire OnStartDecode at init time to support bug 512435
     if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
         mObserver->OnStartDecode(nsnull);
 
     return NS_OK;
--- a/modules/libpr0n/decoders/bmp/nsBMPDecoder.h
+++ b/modules/libpr0n/decoders/bmp/nsBMPDecoder.h
@@ -35,19 +35,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #ifndef _nsBMPDecoder_h
 #define _nsBMPDecoder_h
 
-#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
 #include "imgIDecoder.h"
-#include "imgIContainer.h"
 #include "imgIDecoderObserver.h"
 #include "gfxColor.h"
 
 #define NS_BMPDECODER_CID \
 { /* {78c61626-4d1f-4843-9364-4652d98ff6e1} */ \
   0x78c61626, \
   0x4d1f, \
   0x4843, \
@@ -135,16 +134,22 @@ enum ERLEState {
     eRLEStateInitial,
     eRLEStateNeedSecondEscapeByte,
     eRLEStateNeedXDelta,
     eRLEStateNeedYDelta,    ///< mStateData will hold x delta
     eRLEStateAbsoluteMode,  ///< mStateData will hold count of existing data to read
     eRLEStateAbsoluteModePadded ///< As above, but another byte of data has to be read as padding
 };
 
+namespace mozilla {
+namespace imagelib {
+class RasterImage;
+} // namespace imagelib
+} // namespace mozilla
+
 /**
  * Decoder for BMP-Files, as used by Windows and OS/2
  */
 class nsBMPDecoder : public imgIDecoder
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_IMGIDECODER
@@ -155,17 +160,17 @@ public:
 private:
 
     /** Calculates the red-, green- and blueshift in mBitFields using
      * the bitmasks from mBitFields */
     NS_METHOD CalcBitShift();
 
     nsCOMPtr<imgIDecoderObserver> mObserver;
 
-    nsCOMPtr<imgIContainer> mImage;
+    nsRefPtr<mozilla::imagelib::RasterImage> mImage;
     PRUint32 mFlags;
 
     PRUint32 mPos;
 
     BMPFILEHEADER mBFH;
     BMPINFOHEADER mBIH;
     char mRawBuf[36];
 
--- a/modules/libpr0n/decoders/bmp/nsICODecoder.cpp
+++ b/modules/libpr0n/decoders/bmp/nsICODecoder.cpp
@@ -42,25 +42,26 @@
  * Big-Endian machines like the PowerPC. */
 
 #include <stdlib.h>
 
 #include "nsICODecoder.h"
 
 #include "nsIInputStream.h"
 #include "nsIComponentManager.h"
+#include "RasterImage.h"
 #include "imgIContainerObserver.h"
 
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 
 #include "nsIProperties.h"
 #include "nsISupportsPrimitives.h"
 
-#include "nsAutoPtr.h"
+using namespace mozilla::imagelib;
 
 NS_IMPL_ISUPPORTS1(nsICODecoder, imgIDecoder)
 
 #define ICONCOUNTOFFSET 4
 #define DIRENTRYOFFSET 6
 #define BITMAPINFOSIZE 40
 #define PREFICONSIZE 16
 
@@ -88,18 +89,21 @@ nsICODecoder::nsICODecoder()
 nsICODecoder::~nsICODecoder()
 {
 }
 
 NS_IMETHODIMP nsICODecoder::Init(imgIContainer *aImage,
                                  imgIDecoderObserver *aObserver,
                                  PRUint32 aFlags)
 {
+  NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
+                    "wrong type of imgIContainer for decoding into");
+
   // Grab parameters
-  mImage = aImage;
+  mImage = static_cast<RasterImage*>(aImage);
   mObserver = aObserver;
   mFlags = aFlags;
 
   // Fire OnStartDecode at init time to support bug 512435
   if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
     mObserver->OnStartDecode(nsnull);
 
   return NS_OK;
@@ -275,28 +279,25 @@ nsICODecoder::Write(const char* aBuffer,
       mColors = new colorTable[mNumColors];
       if (!mColors) {
         mError = PR_TRUE;
         return NS_ERROR_OUT_OF_MEMORY;
       }
     }
 
     if (mIsCursor) {
-      nsCOMPtr<nsIProperties> props(do_QueryInterface(mImage));
-      if (props) {
-        nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
-        nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
+      nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
+      nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
 
-        if (intwrapx && intwrapy) {
-          intwrapx->SetData(mDirEntry.mXHotspot);
-          intwrapy->SetData(mDirEntry.mYHotspot);
+      if (intwrapx && intwrapy) {
+        intwrapx->SetData(mDirEntry.mXHotspot);
+        intwrapy->SetData(mDirEntry.mYHotspot);
 
-          props->Set("hotspotX", intwrapx);
-          props->Set("hotspotY", intwrapy);
-        }
+        mImage->Set("hotspotX", intwrapx);
+        mImage->Set("hotspotY", intwrapy);
       }
     }
 
     mCurLine = mDirEntry.mHeight;
     mRow = (PRUint8*)malloc((mDirEntry.mWidth * mBIH.bpp)/8 + 4);
     // +4 because the line is padded to a 4 bit boundary, but I don't want
     // to make exact calculations here, that's unnecessary.
     // Also, it compensates rounding error.
--- a/modules/libpr0n/decoders/bmp/nsICODecoder.h
+++ b/modules/libpr0n/decoders/bmp/nsICODecoder.h
@@ -36,26 +36,32 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #ifndef _nsICODecoder_h
 #define _nsICODecoder_h
 
-#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
 #include "imgIDecoder.h"
 #include "imgIContainer.h"
 #include "imgIDecoderObserver.h"
 #include "nsBMPDecoder.h"
 
 // {CB3EDE1A-0FA5-4e27-AAFE-0F7801E5A1F1}
 #define NS_ICODECODER_CID \
 { 0xcb3ede1a, 0xfa5, 0x4e27, { 0xaa, 0xfe, 0xf, 0x78, 0x1, 0xe5, 0xa1, 0xf1 } }
 
+namespace mozilla {
+namespace imagelib {
+class RasterImage;
+} // namespace imagelib
+} // namespace mozilla
+
 struct IconDirEntry
 {
   PRUint8   mWidth;
   PRUint8   mHeight;
   PRUint8   mColorCount;
   PRUint8   mReserved;
   union {
     PRUint16 mPlanes;   // ICO
@@ -83,17 +89,17 @@ private:
   void ProcessDirEntry(IconDirEntry& aTarget);
   void ProcessInfoHeader();
 
   nsresult SetImageData();
 
   PRUint32 CalcAlphaRowSize();
 
 private:
-  nsCOMPtr<imgIContainer> mImage;
+  nsRefPtr<mozilla::imagelib::RasterImage> mImage;
   nsCOMPtr<imgIDecoderObserver> mObserver;
   PRUint32 mFlags;
   
   PRUint32 mPos;
   PRUint16 mNumIcons;
   PRUint16 mCurrIcon;
   PRUint32 mImageOffset;
 
rename from modules/libpr0n/decoders/icon/nsIconDecoder.cpp
rename to modules/libpr0n/decoders/bmp/nsIconDecoder.cpp
--- a/modules/libpr0n/decoders/icon/nsIconDecoder.cpp
+++ b/modules/libpr0n/decoders/bmp/nsIconDecoder.cpp
@@ -35,26 +35,28 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIconDecoder.h"
 #include "nsIInputStream.h"
-#include "imgIContainer.h"
+#include "RasterImage.h"
 #include "imgIContainerObserver.h"
 #include "nspr.h"
 #include "nsIComponentManager.h"
 #include "nsRect.h"
 #include "nsComponentManagerUtils.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "ImageErrors.h"
 
+using namespace mozilla::imagelib;
+
 NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder)
 NS_IMPL_THREADSAFE_RELEASE(nsIconDecoder)
 
 NS_INTERFACE_MAP_BEGIN(nsIconDecoder)
    NS_INTERFACE_MAP_ENTRY(imgIDecoder)
 NS_INTERFACE_MAP_END_THREADSAFE
 
 
@@ -80,17 +82,20 @@ nsIconDecoder::~nsIconDecoder()
 /** imgIDecoder methods **/
 
 NS_IMETHODIMP nsIconDecoder::Init(imgIContainer *aImage,
                                   imgIDecoderObserver *aObserver,
                                   PRUint32 aFlags)
 {
 
   // Grab parameters
-  mImage = aImage;
+  NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
+                    "wrong type of imgIContainer for decoding into");
+
+  mImage = static_cast<RasterImage*>(aImage);
   mObserver = aObserver;
   mFlags = aFlags;
 
   // Fire OnStartDecode at init time to support bug 512435
   if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
     mObserver->OnStartDecode(nsnull);
 
   return NS_OK;
rename from modules/libpr0n/decoders/icon/nsIconDecoder.h
rename to modules/libpr0n/decoders/bmp/nsIconDecoder.h
--- a/modules/libpr0n/decoders/icon/nsIconDecoder.h
+++ b/modules/libpr0n/decoders/bmp/nsIconDecoder.h
@@ -51,16 +51,21 @@
 #define NS_ICONDECODER_CID                           \
 { /* FFC08380-256C-11d5-9905-001083010E9B */         \
      0xffc08380,                                     \
      0x256c,                                         \
      0x11d5,                                         \
     { 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b }   \
 }
 
+namespace mozilla {
+namespace imagelib {
+class RasterImage;
+} // namespace imagelib
+} // namespace mozilla
 
 //////////////////////////////////////////////////////////////////////////////////////////////
 // The icon decoder is a decoder specifically tailored for loading icons 
 // from the OS. We've defined our own little format to represent these icons
 // and this decoder takes that format and converts it into 24-bit RGB with alpha channel
 // support. It was modeled a bit off the PPM decoder.
 //
 // Assumptions about the decoder:
@@ -80,17 +85,17 @@ class nsIconDecoder : public imgIDecoder
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIDECODER
 
   nsIconDecoder();
   virtual ~nsIconDecoder();
 
-  nsCOMPtr<imgIContainer> mImage;
+  nsRefPtr<mozilla::imagelib::RasterImage> mImage;
   nsCOMPtr<imgIDecoderObserver> mObserver;
   PRUint32 mFlags;
   PRUint8 mWidth;
   PRUint8 mHeight;
   PRUint32 mPixBytesRead;
   PRUint32 mPixBytesTotal;
   PRUint8* mImageData;
   PRUint32 mState;
--- a/modules/libpr0n/decoders/gif/Makefile.in
+++ b/modules/libpr0n/decoders/gif/Makefile.in
@@ -46,14 +46,14 @@ MODULE		= imggif
 LIBRARY_NAME	= imggif_s
 FORCE_STATIC_LIB = 1
 MODULE_NAME	= nsGIFModule2
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS		= nsGIFDecoder2.cpp
 
-# nsGIFDecoder2.cpp includes imgContainer.h
+# nsGIFDecoder2.cpp includes RasterImage.h
 LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src
 
 include $(topsrcdir)/config/rules.mk
 
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp
+++ b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp
@@ -76,16 +76,17 @@ mailing address.
 #include "prmem.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 
 #include "nsGIFDecoder2.h"
 #include "nsIInputStream.h"
 #include "nsIComponentManager.h"
 #include "imgIContainerObserver.h"
+#include "RasterImage.h"
 
 #include "gfxColor.h"
 #include "gfxPlatform.h"
 #include "qcms.h"
 
 /*
  * GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's'
  *
@@ -139,18 +140,21 @@ nsGIFDecoder2::~nsGIFDecoder2()
 //******************************************************************************
 /* void init (in imgIContainer aImage,
               in imgIDecoderObserver aObsever,
               in unsigned long aFlags); */
 NS_IMETHODIMP nsGIFDecoder2::Init(imgIContainer *aImage,
                                   imgIDecoderObserver *aObserver,
                                   PRUint32 aFlags)
 {
+  NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
+                    "wrong type of imgIContainer for decoding into");
+
   // Store parameters
-  mImageContainer = aImage;
+  mImageContainer = static_cast<mozilla::imagelib::RasterImage*>(aImage);
   mObserver = aObserver;
   mFlags = aFlags;
 
   // Fire OnStartDecode at init time to support bug 512435
   if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
     mObserver->OnStartDecode(nsnull);
 
   // Start with the version (GIF89a|GIF87a)
--- a/modules/libpr0n/decoders/gif/nsGIFDecoder2.h
+++ b/modules/libpr0n/decoders/gif/nsGIFDecoder2.h
@@ -51,16 +51,22 @@
 #define NS_GIFDECODER2_CID \
 { /* 797bec5a-1dd2-11b2-a7f8-ca397e0179c4 */         \
      0x797bec5a,                                     \
      0x1dd2,                                         \
      0x11b2,                                         \
     {0xa7, 0xf8, 0xca, 0x39, 0x7e, 0x01, 0x79, 0xc4} \
 }
 
+namespace mozilla {
+namespace imagelib {
+class RasterImage;
+} // namespace imagelib
+} // namespace mozilla
+
 //////////////////////////////////////////////////////////////////////
 // nsGIFDecoder2 Definition
 
 class nsGIFDecoder2 : public imgIDecoder
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIDECODER
@@ -80,17 +86,19 @@ private:
   nsresult  FlushImageData(PRUint32 fromRow, PRUint32 rows);
 
   nsresult  GifWrite(const PRUint8 * buf, PRUint32 numbytes);
   PRUint32  OutputRow();
   PRBool    DoLzw(const PRUint8 *q);
 
   inline int ClearCode() const { return 1 << mGIFStruct.datasize; }
 
-  nsCOMPtr<imgIContainer> mImageContainer;
+  // XXXdholbert This member variable should probably be renamed to "mImage"
+  // for consistency with nsPNGDecoder
+  nsRefPtr<mozilla::imagelib::RasterImage> mImageContainer;
   nsCOMPtr<imgIDecoderObserver> mObserver;
   PRUint32 mFlags;
   PRInt32 mCurrentRow;
   PRInt32 mLastFlushedRow;
 
   PRUint8 *mImageData;       // Pointer to image data in either Cairo or 8bit format
   PRUint32 *mColormap;       // Current colormap to be used in Cairo format
   PRUint32 mColormapSize;
--- a/modules/libpr0n/decoders/icon/Makefile.in
+++ b/modules/libpr0n/decoders/icon/Makefile.in
@@ -78,28 +78,16 @@ endif
 
 
 CPPSRCS		= \
 		nsIconURI.cpp \
 		nsIconModule.cpp \
 		nsIconProtocolHandler.cpp \
 		$(NULL)
 
-ifneq (,$(filter qt gtk2,$(MOZ_WIDGET_TOOLKIT)))
-USE_ICON_DECODER = 1
-endif
-ifeq (,$(filter-out Darwin OS2 BeOS,$(OS_ARCH)))
-USE_ICON_DECODER = 1
-endif
-
-ifdef USE_ICON_DECODER
-CPPSRCS		+= nsIconDecoder.cpp
-DEFINES		+= -DUSE_ICON_DECODER
-endif
-
 XPIDLSRCS	= nsIIconURI.idl
 
 SHARED_LIBRARY_LIBS = $(PLATFORM)/$(LIB_PREFIX)imgicon$(PLATFORM)_s.$(LIB_SUFFIX)
 
 EXTRA_DSO_LDOPTS += \
 		$(EXTRA_DSO_LIBS) \
 		$(MOZ_COMPONENT_LIBS) \
 		$(NULL)
--- a/modules/libpr0n/decoders/icon/nsIconModule.cpp
+++ b/modules/libpr0n/decoders/icon/nsIconModule.cpp
@@ -35,61 +35,41 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/ModuleUtils.h"
 #include "nsServiceManagerUtils.h"
 
-#ifdef USE_ICON_DECODER
-#include "nsIconDecoder.h"
-#endif
 #include "nsIconProtocolHandler.h"
 #include "nsIconURI.h"
 #include "nsIconChannel.h"
 
 // objects that just require generic constructors
 /******************************************************************************
  * Protocol CIDs
  */
 #define NS_ICONPROTOCOL_CID   { 0xd0f9db12, 0x249c, 0x11d5, { 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } } 
 
-#ifdef USE_ICON_DECODER
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconDecoder)
-#endif
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconProtocolHandler)
 
-#ifdef USE_ICON_DECODER
-static const char gIconMimeType[] = "image/icon";
-NS_DEFINE_NAMED_CID(NS_ICONDECODER_CID);
-#endif
-
 NS_DEFINE_NAMED_CID(NS_ICONPROTOCOL_CID);
 
 static const mozilla::Module::CIDEntry kIconCIDs[] = {
-#ifdef USE_ICON_DECODER
-  { &kNS_ICONDECODER_CID, false, NULL, nsIconDecoderConstructor },
-#endif
   { &kNS_ICONPROTOCOL_CID, false, NULL, nsIconProtocolHandlerConstructor },
   { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kIconContracts[] = {
-#ifdef USE_ICON_DECODER
-  { "@mozilla.org/image/decoder;3?type=image/icon", &kNS_ICONDECODER_CID },
-#endif
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-icon", &kNS_ICONPROTOCOL_CID },
   { NULL }
 };
 
 static const mozilla::Module::CategoryEntry kIconCategories[] = {
-#ifdef USE_ICON_DECODER
-  { "Gecko-Content-Viewers", gIconMimeType, "@mozilla.org/content/document-loader-factory;1" },
-#endif
   { NULL }
 };
 
 static void
 IconDecoderModuleDtor()
 {
 #ifdef MOZ_WIDGET_GTK2
   nsIconChannel::Shutdown();
--- a/modules/libpr0n/decoders/jpeg/Makefile.in
+++ b/modules/libpr0n/decoders/jpeg/Makefile.in
@@ -48,10 +48,13 @@ FORCE_STATIC_LIB = 1
 MODULE_NAME	= nsJPEGDecoderModule
 LIBXUL_LIBRARY  = 1
 
 
 CPPSRCS		= nsJPEGDecoder.cpp
 
 CSRCS		= iccjpeg.c
 
+# nsJPEGDecoder.cpp includes RasterImage.h
+LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/
+
 include $(topsrcdir)/config/rules.mk
 
--- a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp
+++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp
@@ -51,16 +51,18 @@
 #include "ImageLogging.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "gfxColor.h"
 
 #include "jerror.h"
 
 #include "gfxPlatform.h"
 
+using namespace mozilla::imagelib;
+
 extern "C" {
 #include "iccjpeg.h"
 
 /* Colorspace conversion (copied from jpegint.h) */
 struct jpeg_color_deconverter {
   JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
   JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
 				JSAMPIMAGE input_buf, JDIMENSION input_row,
@@ -140,19 +142,21 @@ nsJPEGDecoder::~nsJPEGDecoder()
 
 /* void init (in imgIContainer aImage, 
               in imgIDecoderObserver aObserver,
               in unsigned long aFlags); */
 NS_IMETHODIMP nsJPEGDecoder::Init(imgIContainer *aImage, 
                                   imgIDecoderObserver *aObserver,
                                   PRUint32 aFlags)
 {
+  NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
+                    "wrong type of imgIContainer for decoding into");
 
   /* Grab the parameters. */
-  mImage = aImage;
+  mImage = static_cast<RasterImage*>(aImage);
   mObserver = aObserver;
   mFlags = aFlags;
 
   /* Fire OnStartDecode at init time to support bug 512435 */
   if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
     mObserver->OnStartDecode(nsnull);
 
   /* We set up the normal JPEG error routines, then override error_exit. */
--- a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h
+++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h
@@ -36,21 +36,26 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsJPEGDecoder_h__
 #define nsJPEGDecoder_h__
 
+#include "RasterImage.h"
+/* On Windows systems, RasterImage.h brings in 'windows.h', which defines INT32.
+ * But the jpeg decoder has its own definition of INT32. To avoid build issues,
+ * we need to undefine the version from 'windows.h'. */
+#undef INT32
+
 #include "imgIDecoder.h"
 
-#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
 
-#include "imgIContainer.h"
 #include "imgIDecoderObserver.h"
 #include "nsIInputStream.h"
 #include "nsIPipe.h"
 #include "qcms.h"
 
 extern "C" {
 #include "jpeglib.h"
 }
@@ -76,32 +81,38 @@ typedef enum {
     JPEG_DECOMPRESS_PROGRESSIVE,          /* Output progressive pixels */
     JPEG_DECOMPRESS_SEQUENTIAL,           /* Output sequential pixels */
     JPEG_DONE,
     JPEG_SINK_NON_JPEG_TRAILER,          /* Some image files have a */
                                          /* non-JPEG trailer */
     JPEG_ERROR    
 } jstate;
 
+namespace mozilla {
+namespace imagelib {
+class RasterImage;
+} // namespace imagelib
+} // namespace mozilla
+
 class nsJPEGDecoder : public imgIDecoder
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIDECODER
 
   nsJPEGDecoder();
   virtual ~nsJPEGDecoder();
 
   void NotifyDone(PRBool aSuccess);
 
 protected:
   nsresult OutputScanlines(PRBool* suspend);
 
 public:
-  nsCOMPtr<imgIContainer> mImage;
+  nsRefPtr<mozilla::imagelib::RasterImage> mImage;
   nsCOMPtr<imgIDecoderObserver> mObserver;
 
   PRUint32 mFlags;
   PRUint8 *mImageData;
 
   struct jpeg_decompress_struct mInfo;
   struct jpeg_source_mgr mSourceMgr;
   decoder_error_mgr mErr;
--- a/modules/libpr0n/decoders/png/Makefile.in
+++ b/modules/libpr0n/decoders/png/Makefile.in
@@ -45,21 +45,22 @@ include $(DEPTH)/config/autoconf.mk
 MODULE		= imgpng
 LIBRARY_NAME	= imgpng_s
 FORCE_STATIC_LIB = 1
 MODULE_NAME	= nsPNGDecoderModule
 LIBXUL_LIBRARY = 1
 
 EXTRA_DSO_LIBS	= gkgfx
 
-
 CPPSRCS		= nsPNGDecoder.cpp
 
 ifneq (,$(filter png,$(MOZ_IMG_ENCODERS)))
 DEFINES		+= -DMOZ_PNG_WRITE
 endif
 
 ifneq (,$(filter png,$(MOZ_IMG_DECODERS)))
 DEFINES		+= -DMOZ_PNG_READ
 endif
 
+# nsPNGDecoder.cpp includes RasterImage.h
+LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/
+
 include $(topsrcdir)/config/rules.mk
-
--- a/modules/libpr0n/decoders/png/nsPNGDecoder.cpp
+++ b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp
@@ -44,27 +44,30 @@
 #include "nsPNGDecoder.h"
 
 #include "nsMemory.h"
 #include "nsRect.h"
 
 #include "nsIComponentManager.h"
 #include "nsIInputStream.h"
 
+#include "RasterImage.h"
 #include "imgIContainerObserver.h"
 #include "nsIInterfaceRequestorUtils.h"
 
 #include "gfxColor.h"
 #include "nsColor.h"
 
 #include "nspr.h"
 #include "png.h"
 
 #include "gfxPlatform.h"
 
+using namespace mozilla::imagelib;
+
 static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
 static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
                                 png_uint_32 row_num, int pass);
 #ifdef PNG_APNG_SUPPORTED
 static void PNGAPI frame_info_callback(png_structp png_ptr,
                                        png_uint_32 frame_num);
 #endif
 static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr);
@@ -186,28 +189,28 @@ void nsPNGDecoder::SetAnimFrameInfo()
 
   PRUint32 numFrames = 0;
   mImage->GetNumFrames(&numFrames);
 
   mImage->SetFrameTimeout(numFrames - 1, timeout);
 
   if (dispose_op == PNG_DISPOSE_OP_PREVIOUS)
       mImage->SetFrameDisposalMethod(numFrames - 1,
-                                     imgIContainer::kDisposeRestorePrevious);
+                                     RasterImage::kDisposeRestorePrevious);
   else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
       mImage->SetFrameDisposalMethod(numFrames - 1,
-                                     imgIContainer::kDisposeClear);
+                                     RasterImage::kDisposeClear);
   else
       mImage->SetFrameDisposalMethod(numFrames - 1,
-                                     imgIContainer::kDisposeKeep);
+                                     RasterImage::kDisposeKeep);
 
   if (blend_op == PNG_BLEND_OP_SOURCE)
-      mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendSource);
+      mImage->SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendSource);
   /*else // 'over' is the default
-      mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendOver); */
+      mImage->SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendOver); */
 }
 #endif
 
 // set timeout and frame disposal method for the current frame
 void nsPNGDecoder::EndImageFrame()
 {
   PRUint32 numFrames = 1;
 #ifdef PNG_APNG_SUPPORTED
@@ -259,18 +262,20 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgICon
         115,  67,  65,  76, '\0',   /* sCAL */
         112,  72,  89, 115, '\0',   /* pHYs */
         115,  66,  73,  84, '\0',   /* sBIT */
         115,  80,  76,  84, '\0',   /* sPLT */
         116,  69,  88, 116, '\0',   /* tEXt */
         116,  73,  77,  69, '\0',   /* tIME */
         122,  84,  88, 116, '\0'};  /* zTXt */
 #endif
+  NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
+                    "wrong type of imgIContainer for decoding into");
 
-  mImage = aImage;
+  mImage = static_cast<RasterImage*>(aImage);
   mObserver = aObserver;
   mFlags = aFlags;
 
   // Fire OnStartDecode at init time to support bug 512435
   if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
     mObserver->OnStartDecode(nsnull);
 
   // For header-only decodes, we only need a small buffer
--- a/modules/libpr0n/decoders/png/nsPNGDecoder.h
+++ b/modules/libpr0n/decoders/png/nsPNGDecoder.h
@@ -56,16 +56,22 @@
 #define NS_PNGDECODER_CID \
 { /* 36fa00c2-1dd2-11b2-be07-d16eeb4c50ed */         \
      0x36fa00c2,                                     \
      0x1dd2,                                         \
      0x11b2,                                         \
     {0xbe, 0x07, 0xd1, 0x6e, 0xeb, 0x4c, 0x50, 0xed} \
 }
 
+namespace mozilla {
+namespace imagelib {
+class RasterImage;
+} // namespace imagelib
+} // namespace mozilla
+
 class nsPNGDecoder : public imgIDecoder
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIDECODER
 
   nsPNGDecoder();
   virtual ~nsPNGDecoder();
@@ -74,17 +80,17 @@ public:
                    PRInt32 width, PRInt32 height,
                    gfxASurface::gfxImageFormat format);
   void SetAnimFrameInfo();
 
   void EndImageFrame();
   void NotifyDone(PRBool aSuccess);
 
 public:
-  nsCOMPtr<imgIContainer> mImage;
+  nsRefPtr<mozilla::imagelib::RasterImage> mImage;
   nsCOMPtr<imgIDecoderObserver> mObserver;
   PRUint32 mFlags;
 
   png_structp mPNG;
   png_infop mInfo;
   nsIntRect mFrameRect;
   PRUint8 *mCMSLine;
   PRUint8 *interlacebuf;
--- a/modules/libpr0n/public/imgIContainer.idl
+++ b/modules/libpr0n/public/imgIContainer.idl
@@ -66,30 +66,49 @@ native gfxGraphicsFilter(gfxPattern::Gra
 /**
  * imgIContainer is the interface that represents an image. It allows
  * access to frames as Thebes surfaces, and permits users to extract subregions
  * as other imgIContainers. It also allows drawing of images on to Thebes
  * contexts.
  *
  * Internally, imgIContainer also manages animation of images.
  */
-[scriptable, uuid(e6984403-1253-48fa-8a16-a350f76ab6c9)]
+[scriptable, uuid(362e5b5f-f677-49e0-9a3c-03249c794624)]
 interface imgIContainer : nsISupports
 {
   /**
    * The width of the container rectangle.
    */
   readonly attribute PRInt32 width;
 
   /**
    * The height of the container rectangle.
    */
   readonly attribute PRInt32 height;
 
   /**
+    * Enumerated values for the 'type' attribute (below).
+    */
+  const unsigned short TYPE_RASTER = 0;
+  const unsigned short TYPE_VECTOR = 1;
+
+  /**
+   * The type of this image (one of the TYPE_* values above).
+   */
+  readonly attribute unsigned short type;
+
+  /**
+   * Direct C++ accessor for 'type' attribute, for convenience.
+   */
+%{C++
+  virtual PRUint16 GetType() = 0;
+%}
+
+
+  /**
    * Whether this image is animated. You can only be guaranteed that querying
    * this will not throw if STATUS_DECODE_COMPLETE is set on the imgIRequest.
    *
    * @throws NS_ERROR_NOT_AVAILABLE if the animated state cannot be determined.
    */
   readonly attribute boolean animated;
 
   /**
@@ -205,175 +224,25 @@ interface imgIContainer : nsISupports
     * the image is allowed to discard its frame data to save memory.
     *
     * Upon instantiation images have a lock count of zero. It is an error to
     * call this method without first having made a matching lockImage() call.
     * In other words, the lock count is not allowed to be negative.
     */
   void unlockImage();
 
-  /************ Internal libpr0n use only below here. *****************/
-
-  /**
-   * Flags for imgIContainer initialization.
-   *
-   * Meanings:
-   *
-   * INIT_FLAG_NONE: Lack of flags
-   *
-   * INIT_FLAG_DISCARDABLE: The container should be discardable
-   *
-   * INIT_FLAG_DECODE_ON_DRAW: The container should decode on draw rather than
-   * decoding on load.
-   *
-   * INIT_FLAG_MULTIPART: The container will be used to display a stream of
-   * images in a multipart channel. If this flag is set, INIT_FLAG_DISCARDABLE
-   * and INIT_FLAG_DECODE_ON_DRAW must not be set.
-   */
-
-  const long INIT_FLAG_NONE           = 0x0;
-  const long INIT_FLAG_DISCARDABLE    = 0x1;
-  const long INIT_FLAG_DECODE_ON_DRAW = 0x2;
-  const long INIT_FLAG_MULTIPART      = 0x4;
-
-  /**
-   * Creates a new image container.
-   *
-   * @param aObserver Observer to send decoder and animation notifications to.
-   * @param aMimeType The mimetype of the image.
-   * @param aFlags Initialization flags of the INIT_FLAG_* variety.
-   */
-  void init(in imgIDecoderObserver aObserver,
-            in string aMimeType,
-            in PRUint32 aFlags);
-
-  /** 
-   * "Disposal" method indicates how the image should be handled before the
-   *  subsequent image is displayed.
-   *  Don't change these without looking at the implementations using them,
-   *  struct gif_struct::disposal_method and gif_write() in particular.
-   */
-  const long kDisposeClearAll         = -1; // Clear the whole image, revealing
-                                            // what was there before the gif displayed
-  const long kDisposeNotSpecified     =  0; // Leave frame, let new frame draw on top
-  const long kDisposeKeep             =  1; // Leave frame, let new frame draw on top
-  const long kDisposeClear            =  2; // Clear the frame's area, revealing bg
-  const long kDisposeRestorePrevious  =  3; // Restore the previous (composited) frame
-  
-  /*
-   * "Blend" method indicates how the current image is combined with the
-   * previous image.
-   */
-  const long kBlendSource             =  0; // All color components of the frame, including alpha, 
-                                            // overwrite the current contents of the frame's 
-                                            // output buffer region
-  const long kBlendOver               =  1; // The frame should be composited onto the output buffer 
-                                            // based on its alpha, using a simple OVER operation
-  
   /**
    * Animation mode Constants
    *   0 = normal
    *   1 = don't animate
    *   2 = loop once
    */
   const short kNormalAnimMode   = 0;
   const short kDontAnimMode     = 1;
   const short kLoopOnceAnimMode = 2;
 
   attribute unsigned short animationMode;
 
-  /**
-   * The rectangle defining the location and size of the currently displayed frame.
-   * Should be an attribute, but can't be because of reference/pointer
-   * conflicts with native types in xpidl.
-   */
-  [noscript] void getCurrentFrameRect(in nsIntRect aFrameRect);
-
-  /**
-   * The index of the current frame that would be drawn if the image was to be
-   * drawn now.
-   */
-  readonly attribute unsigned long currentFrameIndex;
-
-  /**
-   * The total number of frames in this image.
-   */
-  readonly attribute unsigned long numFrames;
-
-  /**
-   * The size, in bytes, occupied by the significant data portions of the image.
-   * This includes both compressed source data and decoded frames.
-   */
-  readonly attribute unsigned long dataSize;
-
-  void setFrameDisposalMethod(in unsigned long framenumber, in PRInt32 aDisposalMethod);
-  void setFrameBlendMethod(in unsigned long framenumber, in PRInt32 aBlendMethod);
-  void setFrameTimeout(in unsigned long framenumber, in PRInt32 aTimeout);
-  void setFrameHasNoAlpha(in unsigned long framenumber);
-
-  /**
-   * Sets the size of the container. This should only be called by the decoder. This function may be called multiple
-   * times, but will throw an error if subsequent calls do not match the first.
-   */
-  [noscript] void setSize(in long aWidth, in long aHeight);
-
-  /**
-   * Create or re-use a frame at index aFrameNum. It is an error to call this with aFrameNum not in the range [0, numFrames].
-   */
-  [noscript] void ensureCleanFrame(in unsigned long aFramenum, in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat,
-                                   [array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength);
-
-  /**
-   * Adds to the end of the list of frames.
-   */
-  [noscript] void appendFrame(in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat,
-                              [array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength);
-  [noscript] void appendPalettedFrame(in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat, in PRUint8 aPaletteDepth, 
-                                      [array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength,
-                                      [array, size_is(paletteLength)] out PRUint32 paletteData, out unsigned long paletteLength);
-
-  [noscript] void frameUpdated(in unsigned long framenum, in nsIntRect aNewRect);
-
-  /* notification when the current frame is done decoding */
-  void endFrameDecode(in unsigned long framenumber);
-  
-  /* notification that the entire image has been decoded */
-  void decodingComplete();
-  
+  /* Methods to control animation */
   void startAnimation();
-
   void stopAnimation();
-
   void resetAnimation();
-
-  /**
-   * number of times to loop the image.
-   * @note -1 means forever.
-   */
-  attribute long loopCount;
-
-  /* Add compressed source data to the imgContainer.
-   *
-   * The decoder will use this data, either immediately or at draw time, do
-   * decode the image.
-   */
-  [noscript] void addSourceData([array, size_is(aCount), const] in char data,
-                                 in unsigned long aCount);
-
-  /* Called after the all the source data has been added with addSourceData. */
-  [noscript] void sourceDataComplete();
-
-  /* Called for multipart images when there's a new source image to add. */
-  [noscript] void newSourceData();
-
-  /**
-   * A hint of the number of bytes of source data that the image contains. If
-   * called early on, this can help reduce copying and reallocations by
-   * appropriately preallocating the source data buffer.
-   *
-   * We take this approach rather than having the source data management code do
-   * something more complicated (like chunklisting) because HTTP is by far the
-   * dominant source of images, and the Content-Length header is quite reliable.
-   * Thus, pre-allocation simplifies code and reduces the total number of
-   * allocations.
-   */
-  void setSourceSizeHint(in unsigned long sizeHint);
 };
--- a/modules/libpr0n/public/imgIContainerObserver.idl
+++ b/modules/libpr0n/public/imgIContainerObserver.idl
@@ -47,13 +47,14 @@
 interface imgIContainer;
 
 /**
  * imgIContainerObserver interface
  *
  * @author Stuart Parmenter <pavlov@netscape.com>
  * @version 0.1
  */
-[scriptable, uuid(e214c295-4b8e-4aa9-9907-45289e57295b)]
+[scriptable, uuid(aa2068c1-6b91-4f52-8603-487b14ac5f04)]
 interface imgIContainerObserver : nsISupports
 {
-  [noscript] void frameChanged(in imgIContainer aContainer, in nsIntRect aDirtyRect);
+  [noscript] void frameChanged(in imgIContainer aContainer,
+                               [const] in nsIntRect aDirtyRect);
 };
rename from modules/libpr0n/src/imgDiscardTracker.cpp
rename to modules/libpr0n/src/DiscardTracker.cpp
--- a/modules/libpr0n/src/imgDiscardTracker.cpp
+++ b/modules/libpr0n/src/DiscardTracker.cpp
@@ -36,31 +36,34 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIServiceManager.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsITimer.h"
-#include "imgContainer.h"
-#include "imgDiscardTracker.h"
+#include "RasterImage.h"
+#include "DiscardTracker.h"
+
+namespace mozilla {
+namespace imagelib {
 
 static PRBool sInitialized = PR_FALSE;
 static PRBool sTimerOn = PR_FALSE;
 static PRUint32 sMinDiscardTimeoutMs = 10000; /* Default if pref unreadable. */
 static nsITimer *sTimer = nsnull;
-static struct imgDiscardTrackerNode sHead, sSentinel, sTail;
+static struct DiscardTrackerNode sHead, sSentinel, sTail;
 
 /*
  * Puts an image in the back of the tracker queue. If the image is already
  * in the tracker, this removes it first.
  */
 nsresult
-imgDiscardTracker::Reset(imgDiscardTrackerNode *node)
+DiscardTracker::Reset(DiscardTrackerNode *node)
 {
   nsresult rv;
 #ifdef DEBUG
   PRBool isSentinel = (node == &sSentinel);
 
   // Sanity check the node.
   NS_ABORT_IF_FALSE(isSentinel || node->curr, "Node doesn't point to anything!");
 
@@ -93,17 +96,17 @@ imgDiscardTracker::Reset(imgDiscardTrack
 
   return NS_OK;
 }
 
 /*
  * Removes a node from the tracker. No-op if the node is currently untracked.
  */
 void
-imgDiscardTracker::Remove(imgDiscardTrackerNode *node)
+DiscardTracker::Remove(DiscardTrackerNode *node)
 {
   NS_ABORT_IF_FALSE(node != nsnull, "Can't pass null node");
 
   // If we're not in a list, we have nothing to do.
   if ((node->prev == nsnull) || (node->next == nsnull)) {
     NS_ABORT_IF_FALSE(node->prev == node->next,
                       "Node is half in a list!");
     return;
@@ -116,17 +119,17 @@ imgDiscardTracker::Remove(imgDiscardTrac
   // Clean up the node we removed.
   node->prev = node->next = nsnull;
 }
 
 /**
  * Initialize the tracker.
  */
 nsresult
-imgDiscardTracker::Initialize()
+DiscardTracker::Initialize()
 {
   nsresult rv;
 
   // Set up the list. Head<->Sentinel<->Tail
   sHead.curr = sTail.curr = sSentinel.curr = nsnull;
   sHead.prev = sTail.next = nsnull;
   sHead.next = sTail.prev = &sSentinel;
   sSentinel.prev = &sHead;
@@ -147,30 +150,30 @@ imgDiscardTracker::Initialize()
 
   return NS_OK;
 }
 
 /**
  * Shut down the tracker, deallocating the timer.
  */
 void
-imgDiscardTracker::Shutdown()
+DiscardTracker::Shutdown()
 {
   if (sTimer) {
     sTimer->Cancel();
     NS_RELEASE(sTimer);
     sTimer = nsnull;
   }
 }
 
 /**
  * Sets the minimum timeout.
  */
 void
-imgDiscardTracker::ReloadTimeout()
+DiscardTracker::ReloadTimeout()
 {
   nsresult rv;
 
   // read the timeout pref
   PRInt32 discardTimeout;
   nsCOMPtr<nsIPrefBranch2> branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
   rv = branch->GetIntPref(DISCARD_TIMEOUT_PREF, &discardTimeout);
 
@@ -191,17 +194,17 @@ imgDiscardTracker::ReloadTimeout()
     TimerOn();
   }
 }
 
 /**
  * Enables the timer. No-op if the timer is already running.
  */
 nsresult
-imgDiscardTracker::TimerOn()
+DiscardTracker::TimerOn()
 {
   // Nothing to do if the timer's already on.
   if (sTimerOn)
     return NS_OK;
   sTimerOn = PR_TRUE;
 
   // Activate
   return sTimer->InitWithFuncCallback(TimerCallback,
@@ -209,44 +212,47 @@ imgDiscardTracker::TimerOn()
                                       sMinDiscardTimeoutMs,
                                       nsITimer::TYPE_REPEATING_SLACK);
 }
 
 /*
  * Disables the timer. No-op if the timer isn't running.
  */
 void
-imgDiscardTracker::TimerOff()
+DiscardTracker::TimerOff()
 {
   // Nothing to do if the timer's already off.
   if (!sTimerOn)
     return;
   sTimerOn = PR_FALSE;
 
   // Deactivate
   sTimer->Cancel();
 }
 
 /**
  * Routine activated when the timer fires. This discards everything
  * in front of sentinel, and resets the sentinel to the back of the
  * list.
  */
 void
-imgDiscardTracker::TimerCallback(nsITimer *aTimer, void *aClosure)
+DiscardTracker::TimerCallback(nsITimer *aTimer, void *aClosure)
 {
-  imgDiscardTrackerNode *node;
+  DiscardTrackerNode *node;
 
   // Remove and discard everything before the sentinel
   for (node = sSentinel.prev; node != &sHead; node = sSentinel.prev) {
     NS_ABORT_IF_FALSE(node->curr, "empty node!");
     Remove(node);
     node->curr->Discard();
   }
 
   // Append the sentinel to the back of the list
   Reset(&sSentinel);
 
   // If there's nothing in front of the sentinel, the next callback
   // is guaranteed to be a no-op. Disable the timer as an optimization.
   if (sSentinel.prev == &sHead)
     TimerOff();
 }
+
+} // namespace imagelib
+} // namespace mozilla
rename from modules/libpr0n/src/imgDiscardTracker.h
rename to modules/libpr0n/src/DiscardTracker.h
--- a/modules/libpr0n/src/imgDiscardTracker.h
+++ b/modules/libpr0n/src/DiscardTracker.h
@@ -30,55 +30,60 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef __imgDiscardTracker_h__
-#define __imgDiscardTracker_h__
+#ifndef mozilla_imagelib_DiscardTracker_h_
+#define mozilla_imagelib_DiscardTracker_h_
 
 #define DISCARD_TIMEOUT_PREF "image.mem.min_discard_timeout_ms"
 
-class imgContainer;
 class nsITimer;
 
-// Struct to make an imgContainer insertable into the tracker list. This
-// is embedded within each imgContainer object, and we do 'this->curr = this'
-// on imgContainer construction. Thus, an imgContainer must always call
-// imgDiscardTracker::Remove() in its destructor to avoid having the tracker
+namespace mozilla {
+namespace imagelib {
+class RasterImage;
+
+// Struct to make a RasterImage insertable into the tracker list. This
+// is embedded within each RasterImage object, and we do 'this->curr = this'
+// on RasterImage construction. Thus, a RasterImage must always call
+// DiscardTracker::Remove() in its destructor to avoid having the tracker
 // point to bogus memory.
-struct imgDiscardTrackerNode
+struct DiscardTrackerNode
 {
-  // Pointer to the imgContainer that this node tracks
-  imgContainer *curr;
+  // Pointer to the RasterImage that this node tracks
+  RasterImage *curr;
 
   // Pointers to the previous and next nodes in the list
-  imgDiscardTrackerNode *prev, *next;
+  DiscardTrackerNode *prev, *next;
 };
 
 /**
- * This static class maintains a linked list of imgContainer nodes. When Reset()
+ * This static class maintains a linked list of RasterImage nodes. When Reset()
  * is called, the node is removed from its position in the list (if it was there
  * before) and appended to the end. When Remove() is called, the node is removed
  * from the list. The timer fires once every MIN_DISCARD_TIMEOUT_MS ms. When it
  * does, it calls Discard() on each container preceding it, and then appends
  * itself to the end of the list. Thus, the discard timeout varies between
  * MIN_DISCARD_TIMEOUT_MS and 2*MIN_DISCARD_TIMEOUT_MS.
  */
-
-class imgDiscardTracker
+class DiscardTracker
 {
   public:
-    static nsresult Reset(struct imgDiscardTrackerNode *node);
-    static void Remove(struct imgDiscardTrackerNode *node);
+    static nsresult Reset(struct DiscardTrackerNode *node);
+    static void Remove(struct DiscardTrackerNode *node);
     static void Shutdown();
     static void ReloadTimeout();
   private:
     static nsresult Initialize();
     static nsresult TimerOn();
     static void TimerOff();
     static void TimerCallback(nsITimer *aTimer, void *aClosure);
 };
 
-#endif /* __imgDiscardTracker_h__ */
+} // namespace imagelib
+} // namespace mozilla
+
+#endif /* mozilla_imagelib_DiscardTracker_h_ */
new file mode 100644
--- /dev/null
+++ b/modules/libpr0n/src/Image.cpp
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010.
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "Image.h"
+
+namespace mozilla {
+namespace imagelib {
+
+// Constructor
+Image::Image() :
+  mStatusTracker(this),
+  mInitialized(PR_FALSE)
+{
+}
+
+} // namespace imagelib
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/modules/libpr0n/src/Image.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010.
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_IMAGELIB_IMAGE_H_
+#define MOZILLA_IMAGELIB_IMAGE_H_
+
+#include "imgIContainer.h"
+#include "imgStatusTracker.h"
+#include "prtypes.h"
+
+namespace mozilla {
+namespace imagelib {
+
+class Image : public imgIContainer
+{
+public:
+  imgStatusTracker& GetStatusTracker() { return mStatusTracker; }
+  PRBool IsInitialized() const { return mInitialized; }
+
+  /**
+   * Flags for Image initialization.
+   *
+   * Meanings:
+   *
+   * INIT_FLAG_NONE: Lack of flags
+   *
+   * INIT_FLAG_DISCARDABLE: The container should be discardable
+   *
+   * INIT_FLAG_DECODE_ON_DRAW: The container should decode on draw rather than
+   * decoding on load.
+   *
+   * INIT_FLAG_MULTIPART: The container will be used to display a stream of
+   * images in a multipart channel. If this flag is set, INIT_FLAG_DISCARDABLE
+   * and INIT_FLAG_DECODE_ON_DRAW must not be set.
+   */
+  static const PRUint32 INIT_FLAG_NONE           = 0x0;
+  static const PRUint32 INIT_FLAG_DISCARDABLE    = 0x1;
+  static const PRUint32 INIT_FLAG_DECODE_ON_DRAW = 0x2;
+  static const PRUint32 INIT_FLAG_MULTIPART      = 0x4;
+
+  /**
+   * Creates a new image container.
+   *
+   * @param aObserver Observer to send decoder and animation notifications to.
+   * @param aMimeType The mimetype of the image.
+   * @param aFlags Initialization flags of the INIT_FLAG_* variety.
+   */
+  virtual nsresult Init(imgIDecoderObserver* aObserver,
+                        const char* aMimeType,
+                        PRUint32 aFlags) = 0;
+
+  /**
+   * The rectangle defining the location and size of the currently displayed
+   * frame.  Should be an attribute, but can't be because of reference/pointer
+   * conflicts with native types in xpidl.
+   */
+  virtual nsresult GetCurrentFrameRect(nsIntRect& aRect) = 0;
+
+  /**
+   * The index of the current frame that would be drawn if the image was to be
+   * drawn now.
+   */
+  virtual nsresult GetCurrentFrameIndex(PRUint32* aCurrentFrameIdx) = 0;
+
+  /**
+   * The total number of frames in this image.
+   */
+  virtual nsresult GetNumFrames(PRUint32* aNumFrames) = 0;
+
+  /**
+   * The size, in bytes, occupied by the significant data portions of the image.
+   * This includes both compressed source data and decoded frames.
+   */
+  virtual nsresult GetDataSize(PRUint32* aDataSize) = 0;
+
+protected:
+  Image();
+
+  // Member data shared by all implementations of this abstract class
+  imgStatusTracker   mStatusTracker;
+  PRPackedBool       mInitialized;   // Have we been initalized?
+};
+
+} // namespace imagelib
+} // namespace mozilla
+
+#endif // MOZILLA_IMAGELIB_IMAGE_H_
--- a/modules/libpr0n/src/Makefile.in
+++ b/modules/libpr0n/src/Makefile.in
@@ -46,23 +46,24 @@ MODULE		= imglib2
 LIBRARY_NAME	= imglib2_s
 FORCE_STATIC_LIB = 1
 MODULE_NAME	= nsImageLib2Module
 GRE_MODULE	= 1
 LIBXUL_LIBRARY  = 1
 
 
 CPPSRCS		= \
-			imgContainer.cpp \
+			Image.cpp \
+			DiscardTracker.cpp \
+			RasterImage.cpp \
 			imgFrame.cpp \
 			imgLoader.cpp    \
 			imgRequest.cpp   \
 			imgRequestProxy.cpp \
 			imgTools.cpp \
-			imgDiscardTracker.cpp \
                         imgStatusTracker.cpp \
 			$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 # Because imgFrame.cpp includes "cairo.h"
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
 
rename from modules/libpr0n/src/imgContainer.cpp
rename to modules/libpr0n/src/RasterImage.cpp
--- a/modules/libpr0n/src/imgContainer.cpp
+++ b/modules/libpr0n/src/RasterImage.cpp
@@ -42,29 +42,31 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsComponentManagerUtils.h"
 #include "imgIContainerObserver.h"
 #include "ImageErrors.h"
 #include "imgIDecoder.h"
 #include "imgIDecoderObserver.h"
-#include "imgContainer.h"
+#include "RasterImage.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsAutoPtr.h"
 #include "nsStringStream.h"
 #include "prmem.h"
 #include "prlog.h"
 #include "prenv.h"
 #include "nsTime.h"
 #include "ImageLogging.h"
 
 #include "gfxContext.h"
 
+using namespace mozilla::imagelib;
+
 /* Accounting for compressed data */
 #if defined(PR_LOGGING)
 static PRLogModuleInfo *gCompressedImageAccountingLog = PR_NewLogModule ("CompressedImageAccounting");
 #else
 #define gCompressedImageAccountingLog
 #endif
 
 /* We define our own error checking macros here for 2 reasons:
@@ -75,22 +77,22 @@ static PRLogModuleInfo *gCompressedImage
  * with spurious messages about NS_ENSURE_SUCCESS failures.
  *
  * 2) We want to set the internal error flag, shutdown properly,
  * and end up in an error state.
  *
  * So this macro should be called when the desired failure behavior
  * is to put the container into an error state and return failure.
  * It goes without saying that macro won't compile outside of a
- * non-static imgContainer method.
+ * non-static RasterImage method.
  */
 #define LOG_CONTAINER_ERROR                      \
   PR_BEGIN_MACRO                                 \
   PR_LOG (gImgLog, PR_LOG_ERROR,                 \
-          ("ImgContainer: [this=%p] Error "      \
+          ("RasterImage: [this=%p] Error "      \
            "detected at line %u for image of "   \
            "type %s\n", this, __LINE__,          \
            mSourceDataMimeType.get()));          \
   PR_END_MACRO
 
 #define CONTAINER_ENSURE_SUCCESS(status)      \
   PR_BEGIN_MACRO                              \
   nsresult _status = status; /* eval once */  \
@@ -128,36 +130,37 @@ DiscardingEnabled()
     inited = PR_TRUE;
 
     enabled = (PR_GetEnv("MOZ_DISABLE_IMAGE_DISCARD") == nsnull);
   }
 
   return enabled;
 }
 
-NS_IMPL_ISUPPORTS4(imgContainer, imgIContainer, nsITimerCallback, nsIProperties,
+namespace mozilla {
+namespace imagelib {
+
+NS_IMPL_ISUPPORTS4(RasterImage, imgIContainer, nsITimerCallback, nsIProperties,
                    nsISupportsWeakReference)
 
 //******************************************************************************
-imgContainer::imgContainer() :
+RasterImage::RasterImage() :
   mSize(0,0),
   mAnim(nsnull),
   mAnimationMode(kNormalAnimMode),
   mLoopCount(-1),
   mObserver(nsnull),
   mLockCount(0),
-  mStatusTracker(this),
   mDecoder(nsnull),
   mWorker(nsnull),
   mBytesDecoded(0),
   mDecoderFlags(imgIDecoder::DECODER_FLAG_NONE),
   mHasSize(PR_FALSE),
   mDecodeOnDraw(PR_FALSE),
   mMultipart(PR_FALSE),
-  mInitialized(PR_FALSE),
   mDiscardable(PR_FALSE),
   mHasSourceData(PR_FALSE),
   mDecoded(PR_FALSE),
   mHasBeenDecoded(PR_FALSE),
   mWorkerPending(PR_FALSE),
   mInDecoder(PR_FALSE),
   mError(PR_FALSE)
 {
@@ -165,60 +168,58 @@ imgContainer::imgContainer() :
   mDiscardTrackerNode.curr = this;
   mDiscardTrackerNode.prev = mDiscardTrackerNode.next = nsnull;
 
   // Statistics
   num_containers++;
 }
 
 //******************************************************************************
-imgContainer::~imgContainer()
+RasterImage::~RasterImage()
 {
   if (mAnim)
     delete mAnim;
 
   for (unsigned int i = 0; i < mFrames.Length(); ++i)
     delete mFrames[i];
 
   // Discardable statistics
   if (mDiscardable) {
     num_discardable_containers--;
     discardable_source_bytes -= mSourceData.Length();
 
     PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG,
-            ("CompressedImageAccounting: destroying imgContainer %p.  "
+            ("CompressedImageAccounting: destroying RasterImage %p.  "
              "Total Containers: %d, Discardable containers: %d, "
              "Total source bytes: %lld, Source bytes for discardable containers %lld",
              this,
              num_containers,
              num_discardable_containers,
              total_source_bytes,
              discardable_source_bytes));
   }
 
-  imgDiscardTracker::Remove(&mDiscardTrackerNode);
+  DiscardTracker::Remove(&mDiscardTrackerNode);
 
   // If we have a decoder open, shut it down
   if (mDecoder) {
     nsresult rv = ShutdownDecoder(eShutdownIntent_Interrupted);
     if (NS_FAILED(rv))
       NS_WARNING("Failed to shut down decoder in destructor!");
   }
 
   // Total statistics
   num_containers--;
   total_source_bytes -= mSourceData.Length();
 }
 
-//******************************************************************************
-/* void init(in imgIDecoderObserver aObserver, in string aMimeType,
-             in PRUint32 aFlags); */
-NS_IMETHODIMP imgContainer::Init(imgIDecoderObserver *aObserver,
-                                 const char* aMimeType,
-                                 PRUint32 aFlags)
+nsresult
+RasterImage::Init(imgIDecoderObserver *aObserver,
+                  const char* aMimeType,
+                  PRUint32 aFlags)
 {
   // We don't support re-initialization
   if (mInitialized)
     return NS_ERROR_ILLEGAL_VALUE;
 
   // Not sure an error can happen before init, but be safe
   if (mError)
     return NS_ERROR_FAILURE;
@@ -270,37 +271,38 @@ NS_IMETHODIMP imgContainer::Init(imgIDec
 
   return NS_OK;
 }
 
 //******************************************************************************
 /* [noscript] imgIContainer extractFrame(PRUint32 aWhichFrame,
  *                                       [const] in nsIntRect aRegion,
  *                                       in PRUint32 aFlags); */
-NS_IMETHODIMP imgContainer::ExtractFrame(PRUint32 aWhichFrame,
-                                         const nsIntRect &aRegion,
-                                         PRUint32 aFlags,
-                                         imgIContainer **_retval)
+NS_IMETHODIMP
+RasterImage::ExtractFrame(PRUint32 aWhichFrame,
+                          const nsIntRect &aRegion,
+                          PRUint32 aFlags,
+                          imgIContainer **_retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   nsresult rv;
 
   if (aWhichFrame > FRAME_MAX_VALUE)
     return NS_ERROR_INVALID_ARG;
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Disallowed in the API
   if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
     return NS_ERROR_FAILURE;
 
   // Make a new container. This should switch to another class with bug 505959.
-  nsRefPtr<imgContainer> img(new imgContainer());
+  nsRefPtr<RasterImage> img(new RasterImage());
   NS_ENSURE_TRUE(img, NS_ERROR_OUT_OF_MEMORY);
 
   // We don't actually have a mimetype in this case. The empty string tells the
   // init routine not to try to instantiate a decoder. This should be fixed in
   // bug 505959.
   img->Init(nsnull, "", INIT_FLAG_NONE);
   img->SetSize(aRegion.width, aRegion.height);
   img->mDecoded = PR_TRUE; // Also, we need to mark the image as decoded
@@ -343,86 +345,105 @@ NS_IMETHODIMP imgContainer::ExtractFrame
 
   *_retval = img.forget().get();
 
   return NS_OK;
 }
 
 //******************************************************************************
 /* readonly attribute PRInt32 width; */
-NS_IMETHODIMP imgContainer::GetWidth(PRInt32 *aWidth)
+NS_IMETHODIMP
+RasterImage::GetWidth(PRInt32 *aWidth)
 {
   NS_ENSURE_ARG_POINTER(aWidth);
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   *aWidth = mSize.width;
   return NS_OK;
 }
 
 //******************************************************************************
 /* readonly attribute PRInt32 height; */
-NS_IMETHODIMP imgContainer::GetHeight(PRInt32 *aHeight)
+NS_IMETHODIMP
+RasterImage::GetHeight(PRInt32 *aHeight)
 {
   NS_ENSURE_ARG_POINTER(aHeight);
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   *aHeight = mSize.height;
   return NS_OK;
 }
 
-imgFrame *imgContainer::GetImgFrame(PRUint32 framenum)
+//******************************************************************************
+/* unsigned short GetType(); */
+NS_IMETHODIMP
+RasterImage::GetType(PRUint16 *aType)
+{
+  NS_ENSURE_ARG_POINTER(aType);
+
+  *aType = imgIContainer::TYPE_RASTER;
+  return NS_OK;
+}
+
+imgFrame*
+RasterImage::GetImgFrame(PRUint32 framenum)
 {
   nsresult rv = WantDecodedFrames();
   CONTAINER_ENSURE_TRUE(NS_SUCCEEDED(rv), nsnull);
 
   if (!mAnim) {
     NS_ASSERTION(framenum == 0, "Don't ask for a frame > 0 if we're not animated!");
     return mFrames.SafeElementAt(0, nsnull);
   }
   if (mAnim->lastCompositedFrameIndex == PRInt32(framenum))
     return mAnim->compositingFrame;
   return mFrames.SafeElementAt(framenum, nsnull);
 }
 
-imgFrame *imgContainer::GetDrawableImgFrame(PRUint32 framenum)
+imgFrame*
+RasterImage::GetDrawableImgFrame(PRUint32 framenum)
 {
   imgFrame *frame = GetImgFrame(framenum);
 
   // We will return a paletted frame if it's not marked as compositing failed
   // so we can catch crashes for reasons we haven't investigated.
   if (frame && frame->GetCompositingFailed())
     return nsnull;
   return frame;
 }
 
-PRUint32 imgContainer::GetCurrentImgFrameIndex() const
+PRUint32
+RasterImage::GetCurrentImgFrameIndex() const
 {
   if (mAnim)
     return mAnim->currentAnimationFrameIndex;
 
   return 0;
 }
 
-imgFrame *imgContainer::GetCurrentImgFrame()
+imgFrame*
+RasterImage::GetCurrentImgFrame()
 {
   return GetImgFrame(GetCurrentImgFrameIndex());
 }
 
-imgFrame *imgContainer::GetCurrentDrawableImgFrame()
+imgFrame*
+RasterImage::GetCurrentDrawableImgFrame()
 {
   return GetDrawableImgFrame(GetCurrentImgFrameIndex());
 }
 
 //******************************************************************************
 /* readonly attribute boolean currentFrameIsOpaque; */
-NS_IMETHODIMP imgContainer::GetCurrentFrameIsOpaque(PRBool *aIsOpaque)
+NS_IMETHODIMP
+RasterImage::GetCurrentFrameIsOpaque(PRBool *aIsOpaque)
 {
   NS_ENSURE_ARG_POINTER(aIsOpaque);
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   // See if we can get an image frame
   imgFrame *curframe = GetCurrentImgFrame();
@@ -439,19 +460,18 @@ NS_IMETHODIMP imgContainer::GetCurrentFr
     // entire area.
     nsIntRect framerect = curframe->GetRect();
     *aIsOpaque = *aIsOpaque && (framerect != nsIntRect(0, 0, mSize.width, mSize.height));
   }
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* [noscript] void getCurrentFrameRect(nsIntRect rect); */
-NS_IMETHODIMP imgContainer::GetCurrentFrameRect(nsIntRect &aRect)
+nsresult
+RasterImage::GetCurrentFrameRect(nsIntRect &aRect)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Get the current frame
   imgFrame *curframe = GetCurrentImgFrame();
 
   // If we have the frame, use that rectangle
@@ -466,47 +486,46 @@ NS_IMETHODIMP imgContainer::GetCurrentFr
   else {
     aRect.MoveTo(0, 0);
     aRect.SizeTo(0, 0);
   }
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* readonly attribute unsigned long currentFrameIndex; */
-NS_IMETHODIMP imgContainer::GetCurrentFrameIndex(PRUint32 *aCurrentFrameIdx)
+nsresult
+RasterImage::GetCurrentFrameIndex(PRUint32 *aCurrentFrameIdx)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(aCurrentFrameIdx);
   
   *aCurrentFrameIdx = GetCurrentImgFrameIndex();
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* readonly attribute unsigned long numFrames; */
-NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames)
+nsresult
+RasterImage::GetNumFrames(PRUint32 *aNumFrames)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(aNumFrames);
 
   *aNumFrames = mFrames.Length();
   
   return NS_OK;
 }
 
 //******************************************************************************
 /* readonly attribute boolean animated; */
-NS_IMETHODIMP imgContainer::GetAnimated(PRBool *aAnimated)
+NS_IMETHODIMP
+RasterImage::GetAnimated(PRBool *aAnimated)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(aAnimated);
 
   // If we have mAnim, we can know for sure
   if (mAnim) {
@@ -524,19 +543,20 @@ NS_IMETHODIMP imgContainer::GetAnimated(
 
   return NS_OK;
 }
 
 
 //******************************************************************************
 /* [noscript] gfxImageSurface copyFrame(in PRUint32 aWhichFrame,
  *                                      in PRUint32 aFlags); */
-NS_IMETHODIMP imgContainer::CopyFrame(PRUint32 aWhichFrame,
-                                      PRUint32 aFlags,
-                                      gfxImageSurface **_retval)
+NS_IMETHODIMP
+RasterImage::CopyFrame(PRUint32 aWhichFrame,
+                       PRUint32 aFlags,
+                       gfxImageSurface **_retval)
 {
   if (aWhichFrame > FRAME_MAX_VALUE)
     return NS_ERROR_INVALID_ARG;
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Disallowed in the API
@@ -581,19 +601,20 @@ NS_IMETHODIMP imgContainer::CopyFrame(PR
 
   *_retval = imgsurface.forget().get();
   return NS_OK;
 }
 
 //******************************************************************************
 /* [noscript] gfxASurface getFrame(in PRUint32 aWhichFrame,
  *                                 in PRUint32 aFlags); */
-NS_IMETHODIMP imgContainer::GetFrame(PRUint32 aWhichFrame,
-                                     PRUint32 aFlags,
-                                     gfxASurface **_retval)
+NS_IMETHODIMP
+RasterImage::GetFrame(PRUint32 aWhichFrame,
+                      PRUint32 aFlags,
+                      gfxASurface **_retval)
 {
   if (aWhichFrame > FRAME_MAX_VALUE)
     return NS_ERROR_INVALID_ARG;
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Disallowed in the API
@@ -637,19 +658,18 @@ NS_IMETHODIMP imgContainer::GetFrame(PRU
     framesurf = imgsurf;
   }
 
   *_retval = framesurf.forget().get();
 
   return rv;
 }
 
-//******************************************************************************
-/* readonly attribute unsigned long dataSize; */
-NS_IMETHODIMP imgContainer::GetDataSize(PRUint32 *_retval)
+nsresult
+RasterImage::GetDataSize(PRUint32 *_retval)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(_retval);
 
   // Start with 0
   *_retval = 0;
@@ -659,44 +679,48 @@ NS_IMETHODIMP imgContainer::GetDataSize(
   NS_ABORT_IF_FALSE(StoringSourceData() || (*_retval == 0),
                     "Non-zero source data size when we aren't storing it?");
 
   // Account for any uncompressed frames
   *_retval += GetDecodedDataSize();
   return NS_OK;
 }
 
-PRUint32 imgContainer::GetDecodedDataSize()
+PRUint32
+RasterImage::GetDecodedDataSize()
 {
   PRUint32 val = 0;
   for (PRUint32 i = 0; i < mFrames.Length(); ++i) {
     imgFrame *frame = mFrames.SafeElementAt(i, nsnull);
     NS_ABORT_IF_FALSE(frame, "Null frame in frame array!");
     val += frame->EstimateMemoryUsed();
   }
 
   return val;
 }
 
-PRUint32 imgContainer::GetSourceDataSize()
+PRUint32
+RasterImage::GetSourceDataSize()
 {
   return mSourceData.Length();
 }
 
-void imgContainer::DeleteImgFrame(PRUint32 framenum)
+void
+RasterImage::DeleteImgFrame(PRUint32 framenum)
 {
   NS_ABORT_IF_FALSE(framenum < mFrames.Length(), "Deleting invalid frame!");
 
   delete mFrames[framenum];
   mFrames[framenum] = nsnull;
 }
 
-nsresult imgContainer::InternalAddFrameHelper(PRUint32 framenum, imgFrame *aFrame,
-                                              PRUint8 **imageData, PRUint32 *imageLength,
-                                              PRUint32 **paletteData, PRUint32 *paletteLength)
+nsresult
+RasterImage::InternalAddFrameHelper(PRUint32 framenum, imgFrame *aFrame,
+                                    PRUint8 **imageData, PRUint32 *imageLength,
+                                    PRUint32 **paletteData, PRUint32 *paletteLength)
 {
   NS_ABORT_IF_FALSE(framenum <= mFrames.Length(), "Invalid frame index!");
   if (framenum > mFrames.Length())
     return NS_ERROR_INVALID_ARG;
 
   nsAutoPtr<imgFrame> frame(aFrame);
 
   if (paletteData && paletteLength)
@@ -708,25 +732,26 @@ nsresult imgContainer::InternalAddFrameH
   // decoder->Write() call.
   frame->LockImageData();
 
   mFrames.InsertElementAt(framenum, frame.forget());
 
   return NS_OK;
 }
                                   
-nsresult imgContainer::InternalAddFrame(PRUint32 framenum,
-                                        PRInt32 aX, PRInt32 aY,
-                                        PRInt32 aWidth, PRInt32 aHeight,
-                                        gfxASurface::gfxImageFormat aFormat,
-                                        PRUint8 aPaletteDepth,
-                                        PRUint8 **imageData,
-                                        PRUint32 *imageLength,
-                                        PRUint32 **paletteData,
-                                        PRUint32 *paletteLength)
+nsresult
+RasterImage::InternalAddFrame(PRUint32 framenum,
+                              PRInt32 aX, PRInt32 aY,
+                              PRInt32 aWidth, PRInt32 aHeight,
+                              gfxASurface::gfxImageFormat aFormat,
+                              PRUint8 aPaletteDepth,
+                              PRUint8 **imageData,
+                              PRUint32 *imageLength,
+                              PRUint32 **paletteData,
+                              PRUint32 *paletteLength)
 {
   // We assume that we're in the middle of decoding because we unlock the
   // previous frame when we create a new frame, and only when decoding do we
   // lock frames.
   NS_ABORT_IF_FALSE(mInDecoder, "Only decoders may add frames!");
 
   NS_ABORT_IF_FALSE(framenum <= mFrames.Length(), "Invalid frame index!");
   if (framenum > mFrames.Length())
@@ -754,18 +779,18 @@ nsresult imgContainer::InternalAddFrame(
     // Since we're about to add our second frame, initialize animation stuff
     if (!ensureAnimExists())
       return NS_ERROR_OUT_OF_MEMORY;
     
     // If we dispose of the first frame by clearing it, then the
     // First Frame's refresh area is all of itself.
     // RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR)
     PRInt32 frameDisposalMethod = mFrames[0]->GetFrameDisposalMethod();
-    if (frameDisposalMethod == imgIContainer::kDisposeClear ||
-        frameDisposalMethod == imgIContainer::kDisposeRestorePrevious)
+    if (frameDisposalMethod == kDisposeClear ||
+        frameDisposalMethod == kDisposeRestorePrevious)
       mAnim->firstFrameRefreshArea = mFrames[0]->GetRect();
   }
 
   // Calculate firstFrameRefreshArea
   // Some gifs are huge but only have a small area that they animate
   // We only need to refresh that small area when Frame 0 comes around again
   nsIntRect frameRect = frame->GetRect();
   mAnim->firstFrameRefreshArea.UnionRect(mAnim->firstFrameRefreshArea, 
@@ -778,60 +803,60 @@ nsresult imgContainer::InternalAddFrame(
   // count should now be 2.  This must be called after we AppendObject 
   // because StartAnimation checks for > 1 frames
   if (mFrames.Length() == 2)
     StartAnimation();
   
   return rv;
 }
 
-/* [noscript] void appendFrame (in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat, [array, size_is (imageLength)] out PRUint8 imageData, out unsigned long imageLength); */
-NS_IMETHODIMP imgContainer::AppendFrame(PRInt32 aX, PRInt32 aY, PRInt32 aWidth,
-                                        PRInt32 aHeight, 
-                                        gfxASurface::gfxImageFormat aFormat,
-                                        PRUint8 **imageData,
-                                        PRUint32 *imageLength)
+nsresult
+RasterImage::AppendFrame(PRInt32 aX, PRInt32 aY, PRInt32 aWidth,
+                         PRInt32 aHeight,
+                         gfxASurface::gfxImageFormat aFormat,
+                         PRUint8 **imageData,
+                         PRUint32 *imageLength)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(imageData);
   NS_ENSURE_ARG_POINTER(imageLength);
 
   return InternalAddFrame(mFrames.Length(), aX, aY, aWidth, aHeight, aFormat, 
                           /* aPaletteDepth = */ 0, imageData, imageLength,
                           /* aPaletteData = */ nsnull, 
                           /* aPaletteLength = */ nsnull);
 }
 
-/* [noscript] void appendPalettedFrame (in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat, in PRUint8 aPaletteDepth, [array, size_is (imageLength)] out PRUint8 imageData, out unsigned long imageLength, [array, size_is (paletteLength)] out PRUint32 paletteData, out unsigned long paletteLength); */
-NS_IMETHODIMP imgContainer::AppendPalettedFrame(PRInt32 aX, PRInt32 aY,
-                                                PRInt32 aWidth, PRInt32 aHeight,
-                                                gfxASurface::gfxImageFormat aFormat,
-                                                PRUint8 aPaletteDepth,
-                                                PRUint8 **imageData,
-                                                PRUint32 *imageLength,
-                                                PRUint32 **paletteData,
-                                                PRUint32 *paletteLength)
+nsresult
+RasterImage::AppendPalettedFrame(PRInt32 aX, PRInt32 aY,
+                                 PRInt32 aWidth, PRInt32 aHeight,
+                                 gfxASurface::gfxImageFormat aFormat,
+                                 PRUint8 aPaletteDepth,
+                                 PRUint8 **imageData,
+                                 PRUint32 *imageLength,
+                                 PRUint32 **paletteData,
+                                 PRUint32 *paletteLength)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(imageData);
   NS_ENSURE_ARG_POINTER(imageLength);
   NS_ENSURE_ARG_POINTER(paletteData);
   NS_ENSURE_ARG_POINTER(paletteLength);
 
   return InternalAddFrame(mFrames.Length(), aX, aY, aWidth, aHeight, aFormat, 
                           aPaletteDepth, imageData, imageLength,
                           paletteData, paletteLength);
 }
 
-/*  [noscript] void setSize(in long aWidth, in long aHeight); */
-NS_IMETHODIMP imgContainer::SetSize(PRInt32 aWidth, PRInt32 aHeight)
+nsresult
+RasterImage::SetSize(PRInt32 aWidth, PRInt32 aHeight)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Ensure that we have positive values
   // XXX - Why isn't the size unsigned? Should this be changed?
   if ((aWidth < 0) || (aHeight < 0))
     return NS_ERROR_INVALID_ARG;
@@ -852,26 +877,21 @@ NS_IMETHODIMP imgContainer::SetSize(PRIn
 
   // Set the size and flag that we have it
   mSize.SizeTo(aWidth, aHeight);
   mHasSize = PR_TRUE;
 
   return NS_OK;
 }
 
-/*  [noscript] void ensureCleanFrame(in unsigned long aFramenum, in PRInt32 aX, 
-                                     in PRInt32 aY, in PRInt32 aWidth, 
-                                     in PRInt32 aHeight, in gfxImageFormat aFormat, 
-                                     [array, size_is(imageLength)]
-                                       out PRUint8 imageData,
-                                     out unsigned long imageLength); */
-NS_IMETHODIMP imgContainer::EnsureCleanFrame(PRUint32 aFrameNum, PRInt32 aX, PRInt32 aY,
-                                             PRInt32 aWidth, PRInt32 aHeight, 
-                                             gfxASurface::gfxImageFormat aFormat,
-                                             PRUint8 **imageData, PRUint32 *imageLength)
+nsresult
+RasterImage::EnsureCleanFrame(PRUint32 aFrameNum, PRInt32 aX, PRInt32 aY,
+                              PRInt32 aWidth, PRInt32 aHeight,
+                              gfxASurface::gfxImageFormat aFormat,
+                              PRUint8 **imageData, PRUint32 *imageLength)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(imageData);
   NS_ENSURE_ARG_POINTER(imageLength);
   NS_ABORT_IF_FALSE(aFrameNum <= mFrames.Length(), "Invalid frame index!");
   if (aFrameNum > mFrames.Length())
@@ -904,36 +924,35 @@ NS_IMETHODIMP imgContainer::EnsureCleanF
 
   // We can re-use the frame.
   frame->GetImageData(imageData, imageLength);
 
   return NS_OK;
 }
 
 
-//******************************************************************************
-/* void frameUpdated (in unsigned long framenumber, in nsIntRect rect); */
-NS_IMETHODIMP imgContainer::FrameUpdated(PRUint32 aFrameNum, nsIntRect &aUpdatedRect)
+nsresult
+RasterImage::FrameUpdated(PRUint32 aFrameNum, nsIntRect &aUpdatedRect)
 {
   NS_ASSERTION(aFrameNum < mFrames.Length(), "Invalid frame index!");
   if (aFrameNum >= mFrames.Length())
     return NS_ERROR_INVALID_ARG;
 
   imgFrame *frame = GetImgFrame(aFrameNum);
   NS_ABORT_IF_FALSE(frame, "Calling FrameUpdated on frame that doesn't exist!");
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   frame->ImageUpdated(aUpdatedRect);
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* void setFrameDisposalMethod (in unsigned long framenumber, in PRInt32 aDisposalMethod); */
-NS_IMETHODIMP imgContainer::SetFrameDisposalMethod(PRUint32 aFrameNum, PRInt32 aDisposalMethod)
+nsresult
+RasterImage::SetFrameDisposalMethod(PRUint32 aFrameNum,
+                                    PRInt32 aDisposalMethod)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
   if (aFrameNum >= mFrames.Length())
     return NS_ERROR_INVALID_ARG;
 
@@ -942,19 +961,18 @@ NS_IMETHODIMP imgContainer::SetFrameDisp
                     "Calling SetFrameDisposalMethod on frame that doesn't exist!");
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   frame->SetFrameDisposalMethod(aDisposalMethod);
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* void setFrameTimeout (in unsigned long framenumber, in PRInt32 aTimeout); */
-NS_IMETHODIMP imgContainer::SetFrameTimeout(PRUint32 aFrameNum, PRInt32 aTimeout)
+nsresult
+RasterImage::SetFrameTimeout(PRUint32 aFrameNum, PRInt32 aTimeout)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
   if (aFrameNum >= mFrames.Length())
     return NS_ERROR_INVALID_ARG;
 
@@ -962,19 +980,18 @@ NS_IMETHODIMP imgContainer::SetFrameTime
   NS_ABORT_IF_FALSE(frame, "Calling SetFrameTimeout on frame that doesn't exist!");
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   frame->SetTimeout(aTimeout);
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* void setFrameBlendMethod (in unsigned long framenumber, in PRInt32 aBlendMethod); */
-NS_IMETHODIMP imgContainer::SetFrameBlendMethod(PRUint32 aFrameNum, PRInt32 aBlendMethod)
+nsresult
+RasterImage::SetFrameBlendMethod(PRUint32 aFrameNum, PRInt32 aBlendMethod)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
   if (aFrameNum >= mFrames.Length())
     return NS_ERROR_INVALID_ARG;
 
@@ -982,20 +999,18 @@ NS_IMETHODIMP imgContainer::SetFrameBlen
   NS_ABORT_IF_FALSE(frame, "Calling SetFrameBlendMethod on frame that doesn't exist!");
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   frame->SetBlendMethod(aBlendMethod);
 
   return NS_OK;
 }
 
-
-//******************************************************************************
-/* void setFrameHasNoAlpha (in unsigned long framenumber); */
-NS_IMETHODIMP imgContainer::SetFrameHasNoAlpha(PRUint32 aFrameNum)
+nsresult
+RasterImage::SetFrameHasNoAlpha(PRUint32 aFrameNum)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
   if (aFrameNum >= mFrames.Length())
     return NS_ERROR_INVALID_ARG;
 
@@ -1003,34 +1018,32 @@ NS_IMETHODIMP imgContainer::SetFrameHasN
   NS_ABORT_IF_FALSE(frame, "Calling SetFrameHasNoAlpha on frame that doesn't exist!");
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   frame->SetHasNoAlpha();
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* void endFrameDecode (in unsigned long framenumber); */
-NS_IMETHODIMP imgContainer::EndFrameDecode(PRUint32 aFrameNum)
+nsresult
+RasterImage::EndFrameDecode(PRUint32 aFrameNum)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Assume there's another frame.
   // currentDecodingFrameIndex is 0 based, aFrameNum is 1 based
   if (mAnim)
     mAnim->currentDecodingFrameIndex = aFrameNum;
   
   return NS_OK;
 }
 
-//******************************************************************************
-/* void decodingComplete (); */
-NS_IMETHODIMP imgContainer::DecodingComplete(void)
+nsresult
+RasterImage::DecodingComplete()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Flag that we're done decoding.
   // XXX - these should probably be combined when we fix animated image
   // discarding with bug 500402.
   mDecoded = PR_TRUE;
@@ -1039,17 +1052,17 @@ NS_IMETHODIMP imgContainer::DecodingComp
     mAnim->doneDecoding = PR_TRUE;
 
   nsresult rv;
 
   // We now have one of the qualifications for discarding. Re-evaluate.
   if (CanDiscard()) {
     NS_ABORT_IF_FALSE(!DiscardingActive(),
                       "We shouldn't have been discardable before this");
-    rv = imgDiscardTracker::Reset(&mDiscardTrackerNode);
+    rv = DiscardTracker::Reset(&mDiscardTrackerNode);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // If there's only 1 frame, optimize it. Optimizing animated images
   // is not supported.
   //
   // We don't optimize the frame for multipart images because we reuse
   // the frame.
@@ -1058,37 +1071,39 @@ NS_IMETHODIMP imgContainer::DecodingComp
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 //******************************************************************************
 /* attribute unsigned short animationMode; */
-NS_IMETHODIMP imgContainer::GetAnimationMode(PRUint16 *aAnimationMode)
+NS_IMETHODIMP
+RasterImage::GetAnimationMode(PRUint16 *aAnimationMode)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(aAnimationMode);
   
   *aAnimationMode = mAnimationMode;
   return NS_OK;
 }
 
 //******************************************************************************
 /* attribute unsigned short animationMode; */
-NS_IMETHODIMP imgContainer::SetAnimationMode(PRUint16 aAnimationMode)
+NS_IMETHODIMP
+RasterImage::SetAnimationMode(PRUint16 aAnimationMode)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
-  NS_ASSERTION(aAnimationMode == imgIContainer::kNormalAnimMode ||
-               aAnimationMode == imgIContainer::kDontAnimMode ||
-               aAnimationMode == imgIContainer::kLoopOnceAnimMode,
+  NS_ASSERTION(aAnimationMode == kNormalAnimMode ||
+               aAnimationMode == kDontAnimMode ||
+               aAnimationMode == kLoopOnceAnimMode,
                "Wrong Animation Mode is being set!");
   
   switch (mAnimationMode = aAnimationMode) {
     case kDontAnimMode:
       StopAnimation();
       break;
     case kNormalAnimMode:
       if (mLoopCount != 0 || 
@@ -1101,17 +1116,18 @@ NS_IMETHODIMP imgContainer::SetAnimation
       break;
   }
   
   return NS_OK;
 }
 
 //******************************************************************************
 /* void startAnimation () */
-NS_IMETHODIMP imgContainer::StartAnimation()
+NS_IMETHODIMP
+RasterImage::StartAnimation()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   if (mAnimationMode == kDontAnimMode || 
       (mAnim && (mAnim->timer || mAnim->animating)))
     return NS_OK;
   
@@ -1138,17 +1154,18 @@ NS_IMETHODIMP imgContainer::StartAnimati
                                    timeout, nsITimer::TYPE_REPEATING_SLACK);
   }
   
   return NS_OK;
 }
 
 //******************************************************************************
 /* void stopAnimation (); */
-NS_IMETHODIMP imgContainer::StopAnimation()
+NS_IMETHODIMP
+RasterImage::StopAnimation()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   if (mAnim) {
     mAnim->animating = PR_FALSE;
 
     if (!mAnim->timer)
@@ -1158,17 +1175,18 @@ NS_IMETHODIMP imgContainer::StopAnimatio
     mAnim->timer = nsnull;
   }
 
   return NS_OK;
 }
 
 //******************************************************************************
 /* void resetAnimation (); */
-NS_IMETHODIMP imgContainer::ResetAnimation()
+NS_IMETHODIMP
+RasterImage::ResetAnimation()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   if (mAnimationMode == kDontAnimMode || 
       !mAnim || mAnim->currentAnimationFrameIndex == 0)
     return NS_OK;
 
@@ -1190,59 +1208,41 @@ NS_IMETHODIMP imgContainer::ResetAnimati
   if (oldAnimating && observer)
     observer->FrameChanged(this, &(mAnim->firstFrameRefreshArea));
 
   if (oldAnimating)
     return StartAnimation();
   return NS_OK;
 }
 
-//******************************************************************************
-/* attribute long loopCount; */
-NS_IMETHODIMP imgContainer::GetLoopCount(PRInt32 *aLoopCount)
+void
+RasterImage::SetLoopCount(PRInt32 aLoopCount)
 {
   if (mError)
-    return NS_ERROR_FAILURE;
-
-  NS_ENSURE_ARG_POINTER(aLoopCount);
-  
-  *aLoopCount = mLoopCount;
-  
-  return NS_OK;
-}
-
-//******************************************************************************
-/* attribute long loopCount; */
-NS_IMETHODIMP imgContainer::SetLoopCount(PRInt32 aLoopCount)
-{
-  if (mError)
-    return NS_ERROR_FAILURE;
+    return;
 
   // -1  infinite
   //  0  no looping, one iteration
   //  1  one loop, two iterations
   //  ...
   mLoopCount = aLoopCount;
-
-  return NS_OK;
 }
 
-//******************************************************************************
-/* void addSourceData(in nsIInputStream aInputStream, in unsigned long aCount); */
-NS_IMETHODIMP imgContainer::AddSourceData(const char *aBuffer, PRUint32 aCount)
+nsresult
+RasterImage::AddSourceData(const char *aBuffer, PRUint32 aCount)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(aBuffer);
   nsresult rv = NS_OK;
 
   // We should not call this if we're not initialized
   NS_ABORT_IF_FALSE(mInitialized, "Calling AddSourceData() on uninitialized "
-                                  "imgContainer!");
+                                  "RasterImage!");
 
   // We should not call this if we're already finished adding source data
   NS_ABORT_IF_FALSE(!mHasSourceData, "Calling AddSourceData() after calling "
                                      "sourceDataComplete()!");
 
   // This call should come straight from necko - no reentrancy allowed
   NS_ABORT_IF_FALSE(!mInDecoder, "Re-entrant call to AddSourceData!");
 
@@ -1269,17 +1269,17 @@ NS_IMETHODIMP imgContainer::AddSourceDat
     }
   }
 
   // Statistics
   total_source_bytes += aCount;
   if (mDiscardable)
     discardable_source_bytes += aCount;
   PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG,
-          ("CompressedImageAccounting: Added compressed data to imgContainer %p (%s). "
+          ("CompressedImageAccounting: Added compressed data to RasterImage %p (%s). "
            "Total Containers: %d, Discardable containers: %d, "
            "Total source bytes: %lld, Source bytes for discardable containers %lld",
            this,
            mSourceDataMimeType.get(),
            num_containers,
            num_discardable_containers,
            total_source_bytes,
            discardable_source_bytes));
@@ -1301,19 +1301,18 @@ get_header_str (char *buf, char *data, P
   for (i = 0; i < n; i++) {
     buf[i * 2]     = hex[(data[i] >> 4) & 0x0f];
     buf[i * 2 + 1] = hex[data[i] & 0x0f];
   }
 
   buf[i * 2] = 0;
 }
 
-//******************************************************************************
-/* void sourceDataComplete(); */
-NS_IMETHODIMP imgContainer::SourceDataComplete()
+nsresult
+RasterImage::SourceDataComplete()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // If we've been called before, ignore. Otherwise, flag that we have everything
   if (mHasSourceData)
     return NS_OK;
   mHasSourceData = PR_TRUE;
@@ -1345,36 +1344,35 @@ NS_IMETHODIMP imgContainer::SourceDataCo
   // Free up any extra space in the backing buffer
   mSourceData.Compact();
 
   // Log header information
   if (PR_LOG_TEST(gCompressedImageAccountingLog, PR_LOG_DEBUG)) {
     char buf[9];
     get_header_str(buf, mSourceData.Elements(), mSourceData.Length());
     PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG,
-            ("CompressedImageAccounting: imgContainer::SourceDataComplete() - data "
+            ("CompressedImageAccounting: RasterImage::SourceDataComplete() - data "
              "is done for container %p (%s) - header %p is 0x%s (length %d)",
              this,
              mSourceDataMimeType.get(),
              mSourceData.Elements(),
              buf,
              mSourceData.Length()));
   }
 
   // We now have one of the qualifications for discarding. Re-evaluate.
   if (CanDiscard()) {
-    nsresult rv = imgDiscardTracker::Reset(&mDiscardTrackerNode);
+    nsresult rv = DiscardTracker::Reset(&mDiscardTrackerNode);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
   return NS_OK;
 }
 
-//******************************************************************************
-/* void newSourceData(); */
-NS_IMETHODIMP imgContainer::NewSourceData()
+nsresult
+RasterImage::NewSourceData()
 {
   nsresult rv;
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   // The source data should be complete before calling this
   NS_ABORT_IF_FALSE(mHasSourceData,
@@ -1407,34 +1405,34 @@ NS_IMETHODIMP imgContainer::NewSourceDat
   // We're decode-on-load here. Open up a new decoder just like what happens when
   // we call Init() for decode-on-load images.
   rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE);
   CONTAINER_ENSURE_SUCCESS(rv);
 
   return NS_OK;
 }
 
-//******************************************************************************
-/* void setSourceSizeHint(in unsigned long sizeHint); */
-NS_IMETHODIMP imgContainer::SetSourceSizeHint(PRUint32 sizeHint)
+nsresult
+RasterImage::SetSourceSizeHint(PRUint32 sizeHint)
 {
   if (sizeHint && StoringSourceData())
     mSourceData.SetCapacity(sizeHint);
   return NS_OK;
 }
 
 //******************************************************************************
 /* void notify(in nsITimer timer); */
-NS_IMETHODIMP imgContainer::Notify(nsITimer *timer)
+NS_IMETHODIMP
+RasterImage::Notify(nsITimer *timer)
 {
   // This should never happen since the timer is only set up in StartAnimation()
   // after mAnim is checked to exist.
   NS_ENSURE_TRUE(mAnim, NS_ERROR_UNEXPECTED);
   NS_ASSERTION(mAnim->timer == timer,
-               "imgContainer::Notify() called with incorrect timer");
+               "RasterImage::Notify() called with incorrect timer");
 
   if (!mAnim->animating || !mAnim->timer)
     return NS_OK;
 
   nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
   if (!observer) {
     // the imgRequest that owns us is dead, we should die now too.
     StopAnimation();
@@ -1485,17 +1483,17 @@ NS_IMETHODIMP imgContainer::Notify(nsITi
   } else if (nextFrameIndex == mAnim->currentDecodingFrameIndex) {
     // Uh oh, the frame we want to show is currently being decoded (partial)
     // Wait a bit and try again
     mAnim->timer->SetDelay(100);
     return NS_OK;
   } else { //  (nextFrameIndex > currentDecodingFrameIndex)
     // We shouldn't get here. However, if we are requesting a frame
     // that hasn't been decoded yet, go back to the last frame decoded
-    NS_WARNING("imgContainer::Notify()  Frame is passed decoded frame");
+    NS_WARNING("RasterImage::Notify()  Frame is passed decoded frame");
     nextFrameIndex = mAnim->currentDecodingFrameIndex;
     if (!(nextFrame = mFrames[nextFrameIndex])) {
       // something wrong with the next frame, skip it
       mAnim->currentAnimationFrameIndex = nextFrameIndex;
       mAnim->timer->SetDelay(100);
       return NS_OK;
     }
     timeout = nextFrame->GetTimeout();
@@ -1516,17 +1514,17 @@ NS_IMETHODIMP imgContainer::Notify(nsITi
     imgFrame *prevFrame = mFrames[previousFrameIndex];
     if (!prevFrame)
       return NS_OK;
 
     // Change frame and announce it
     if (NS_FAILED(DoComposite(&frameToUse, &dirtyRect, prevFrame,
                               nextFrame, nextFrameIndex))) {
       // something went wrong, move on to next
-      NS_WARNING("imgContainer::Notify(): Composing Frame Failed\n");
+      NS_WARNING("RasterImage::Notify(): Composing Frame Failed\n");
       nextFrame->SetCompositingFailed(PR_TRUE);
       mAnim->currentAnimationFrameIndex = nextFrameIndex;
       return NS_OK;
     } else {
       nextFrame->SetCompositingFailed(PR_FALSE);
     }
   }
   // Set currentAnimationFrameIndex at the last possible moment
@@ -1535,94 +1533,95 @@ NS_IMETHODIMP imgContainer::Notify(nsITi
   observer->FrameChanged(this, &dirtyRect);
   
   return NS_OK;
 }
 
 //******************************************************************************
 // DoComposite gets called when the timer for animation get fired and we have to
 // update the composited frame of the animation.
-nsresult imgContainer::DoComposite(imgFrame** aFrameToUse,
-                                   nsIntRect* aDirtyRect,
-                                   imgFrame* aPrevFrame,
-                                   imgFrame* aNextFrame,
-                                   PRInt32 aNextFrameIndex)
+nsresult
+RasterImage::DoComposite(imgFrame** aFrameToUse,
+                         nsIntRect* aDirtyRect,
+                         imgFrame* aPrevFrame,
+                         imgFrame* aNextFrame,
+                         PRInt32 aNextFrameIndex)
 {
   NS_ENSURE_ARG_POINTER(aDirtyRect);
   NS_ENSURE_ARG_POINTER(aPrevFrame);
   NS_ENSURE_ARG_POINTER(aNextFrame);
   NS_ENSURE_ARG_POINTER(aFrameToUse);
 
   PRInt32 prevFrameDisposalMethod = aPrevFrame->GetFrameDisposalMethod();
-  if (prevFrameDisposalMethod == imgIContainer::kDisposeRestorePrevious &&
+  if (prevFrameDisposalMethod == kDisposeRestorePrevious &&
       !mAnim->compositingPrevFrame)
-    prevFrameDisposalMethod = imgIContainer::kDisposeClear;
+    prevFrameDisposalMethod = kDisposeClear;
 
   nsIntRect prevFrameRect = aPrevFrame->GetRect();
   PRBool isFullPrevFrame = (prevFrameRect.x == 0 && prevFrameRect.y == 0 &&
                             prevFrameRect.width == mSize.width &&
                             prevFrameRect.height == mSize.height);
 
   // Optimization: DisposeClearAll if the previous frame is the same size as
   //               container and it's clearing itself
   if (isFullPrevFrame && 
-      (prevFrameDisposalMethod == imgIContainer::kDisposeClear))
-    prevFrameDisposalMethod = imgIContainer::kDisposeClearAll;
+      (prevFrameDisposalMethod == kDisposeClear))
+    prevFrameDisposalMethod = kDisposeClearAll;
 
   PRInt32 nextFrameDisposalMethod = aNextFrame->GetFrameDisposalMethod();
   nsIntRect nextFrameRect = aNextFrame->GetRect();
   PRBool isFullNextFrame = (nextFrameRect.x == 0 && nextFrameRect.y == 0 &&
                             nextFrameRect.width == mSize.width &&
                             nextFrameRect.height == mSize.height);
 
   if (!aNextFrame->GetIsPaletted()) {
     // Optimization: Skip compositing if the previous frame wants to clear the
     //               whole image
-    if (prevFrameDisposalMethod == imgIContainer::kDisposeClearAll) {
+    if (prevFrameDisposalMethod == kDisposeClearAll) {
       aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
       *aFrameToUse = aNextFrame;
       return NS_OK;
     }
   
     // Optimization: Skip compositing if this frame is the same size as the
     //               container and it's fully drawing over prev frame (no alpha)
     if (isFullNextFrame &&
-        (nextFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious) &&
+        (nextFrameDisposalMethod != kDisposeRestorePrevious) &&
         !aNextFrame->GetHasAlpha()) {
       aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
       *aFrameToUse = aNextFrame;
       return NS_OK;
     }
   }
 
   // Calculate area that needs updating
   switch (prevFrameDisposalMethod) {
     default:
-    case imgIContainer::kDisposeNotSpecified:
-    case imgIContainer::kDisposeKeep:
+    case kDisposeNotSpecified:
+    case kDisposeKeep:
       *aDirtyRect = nextFrameRect;
       break;
 
-    case imgIContainer::kDisposeClearAll:
+    case kDisposeClearAll:
       // Whole image container is cleared
       aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
       break;
 
-    case imgIContainer::kDisposeClear:
+    case kDisposeClear:
       // Calc area that needs to be redrawn (the combination of previous and
       // this frame)
       // XXX - This could be done with multiple framechanged calls
       //       Having prevFrame way at the top of the image, and nextFrame
       //       way at the bottom, and both frames being small, we'd be
       //       telling framechanged to refresh the whole image when only two
       //       small areas are needed.
       aDirtyRect->UnionRect(nextFrameRect, prevFrameRect);
       break;
 
-    case imgIContainer::kDisposeRestorePrevious:
+    case kDisposeRestorePrevious:
       aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
       break;
   }
 
   // Optimization:
   //   Skip compositing if the last composited frame is this frame
   //   (Only one composited frame was made for this animation.  Example:
   //    Only Frame 3 of a 10 frame image required us to build a composite frame
@@ -1674,39 +1673,39 @@ nsresult imgContainer::DoComposite(imgFr
         doDisposal = PR_FALSE;  
       }
     }      
   }
 
   if (doDisposal) {
     // Dispose of previous: clear, restore, or keep (copy)
     switch (prevFrameDisposalMethod) {
-      case imgIContainer::kDisposeClear:
+      case kDisposeClear:
         if (needToBlankComposite) {
           // If we just created the composite, it could have anything in it's
           // buffer. Clear whole frame
           ClearFrame(mAnim->compositingFrame);
         } else {
           // Only blank out previous frame area (both color & Mask/Alpha)
           ClearFrame(mAnim->compositingFrame, prevFrameRect);
         }
         break;
   
-      case imgIContainer::kDisposeClearAll:
+      case kDisposeClearAll:
         ClearFrame(mAnim->compositingFrame);
         break;
   
-      case imgIContainer::kDisposeRestorePrevious:
+      case kDisposeRestorePrevious:
         // It would be better to copy only the area changed back to
         // compositingFrame.
         if (mAnim->compositingPrevFrame) {
           CopyFrameImage(mAnim->compositingPrevFrame, mAnim->compositingFrame);
   
           // destroy only if we don't need it for this frame's disposal
-          if (nextFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious)
+          if (nextFrameDisposalMethod != kDisposeRestorePrevious)
             mAnim->compositingPrevFrame = nsnull;
         } else {
           ClearFrame(mAnim->compositingFrame);
         }
         break;
       
       default:
         // Copy previous frame into compositingFrame before we put the new frame on top
@@ -1734,18 +1733,18 @@ nsresult imgContainer::DoComposite(imgFr
     // If we just created the composite, it could have anything in it's
     // buffers. Clear them
     ClearFrame(mAnim->compositingFrame);
   }
 
   // Check if the frame we are composing wants the previous image restored afer
   // it is done. Don't store it (again) if last frame wanted its image restored
   // too
-  if ((nextFrameDisposalMethod == imgIContainer::kDisposeRestorePrevious) &&
-      (prevFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious)) {
+  if ((nextFrameDisposalMethod == kDisposeRestorePrevious) &&
+      (prevFrameDisposalMethod != kDisposeRestorePrevious)) {
     // We are storing the whole image.
     // It would be better if we just stored the area that nextFrame is going to
     // overwrite.
     if (!mAnim->compositingPrevFrame) {
       mAnim->compositingPrevFrame = new imgFrame();
       if (!mAnim->compositingPrevFrame) {
         NS_WARNING("Failed to init compositingFrame!\n");
         return NS_ERROR_OUT_OF_MEMORY;
@@ -1779,32 +1778,33 @@ nsresult imgContainer::DoComposite(imgFr
   if (isFullNextFrame && mAnimationMode == kNormalAnimMode && mLoopCount != 0 &&
       !aNextFrame->GetIsPaletted()) {
     // We have a composited full frame
     // Store the composited frame into the mFrames[..] so we don't have to
     // continuously re-build it
     // Then set the previous frame's disposal to CLEAR_ALL so we just draw the
     // frame next time around
     if (CopyFrameImage(mAnim->compositingFrame, aNextFrame)) {
-      aPrevFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClearAll);
+      aPrevFrame->SetFrameDisposalMethod(kDisposeClearAll);
       mAnim->lastCompositedFrameIndex = -1;
       *aFrameToUse = aNextFrame;
       return NS_OK;
     }
   }
 
   mAnim->lastCompositedFrameIndex = aNextFrameIndex;
   *aFrameToUse = mAnim->compositingFrame;
 
   return NS_OK;
 }
 
 //******************************************************************************
 // Fill aFrame with black. Does also clears the mask.
-void imgContainer::ClearFrame(imgFrame *aFrame)
+void
+RasterImage::ClearFrame(imgFrame *aFrame)
 {
   if (!aFrame)
     return;
 
   nsresult rv = aFrame->LockImageData();
   if (NS_FAILED(rv))
     return;
 
@@ -1815,17 +1815,18 @@ void imgContainer::ClearFrame(imgFrame *
   gfxContext ctx(surf);
   ctx.SetOperator(gfxContext::OPERATOR_CLEAR);
   ctx.Paint();
 
   aFrame->UnlockImageData();
 }
 
 //******************************************************************************
-void imgContainer::ClearFrame(imgFrame *aFrame, nsIntRect &aRect)
+void
+RasterImage::ClearFrame(imgFrame *aFrame, nsIntRect &aRect)
 {
   if (!aFrame || aRect.width <= 0 || aRect.height <= 0)
     return;
 
   nsresult rv = aFrame->LockImageData();
   if (NS_FAILED(rv))
     return;
 
@@ -1840,18 +1841,19 @@ void imgContainer::ClearFrame(imgFrame *
 
   aFrame->UnlockImageData();
 }
 
 
 //******************************************************************************
 // Whether we succeed or fail will not cause a crash, and there's not much
 // we can do about a failure, so there we don't return a nsresult
-PRBool imgContainer::CopyFrameImage(imgFrame *aSrcFrame,
-                                    imgFrame *aDstFrame)
+PRBool
+RasterImage::CopyFrameImage(imgFrame *aSrcFrame,
+                            imgFrame *aDstFrame)
 {
   PRUint8* aDataSrc;
   PRUint8* aDataDest;
   PRUint32 aDataLengthSrc;
   PRUint32 aDataLengthDest;
 
   if (!aSrcFrame || !aDstFrame)
     return PR_FALSE;
@@ -1874,49 +1876,50 @@ PRBool imgContainer::CopyFrameImage(imgF
 
 //******************************************************************************
 /* 
  * aSrc is the current frame being drawn,
  * aDst is the composition frame where the current frame is drawn into.
  * aSrcRect is the size of the current frame, and the position of that frame
  *          in the composition frame.
  */
-nsresult imgContainer::DrawFrameTo(imgFrame *aSrc,
-                                   imgFrame *aDst, 
-                                   nsIntRect& aSrcRect)
+nsresult
+RasterImage::DrawFrameTo(imgFrame *aSrc,
+                         imgFrame *aDst,
+                         nsIntRect& aSrcRect)
 {
   NS_ENSURE_ARG_POINTER(aSrc);
   NS_ENSURE_ARG_POINTER(aDst);
 
   nsIntRect dstRect = aDst->GetRect();
 
   // According to both AGIF and APNG specs, offsets are unsigned
   if (aSrcRect.x < 0 || aSrcRect.y < 0) {
-    NS_WARNING("imgContainer::DrawFrameTo: negative offsets not allowed");
+    NS_WARNING("RasterImage::DrawFrameTo: negative offsets not allowed");
     return NS_ERROR_FAILURE;
   }
   // Outside the destination frame, skip it
   if ((aSrcRect.x > dstRect.width) || (aSrcRect.y > dstRect.height)) {
     return NS_OK;
   }
 
   if (aSrc->GetIsPaletted()) {
     // Larger than the destination frame, clip it
     PRInt32 width = PR_MIN(aSrcRect.width, dstRect.width - aSrcRect.x);
     PRInt32 height = PR_MIN(aSrcRect.height, dstRect.height - aSrcRect.y);
 
     // The clipped image must now fully fit within destination image frame
     NS_ASSERTION((aSrcRect.x >= 0) && (aSrcRect.y >= 0) &&
                  (aSrcRect.x + width <= dstRect.width) &&
                  (aSrcRect.y + height <= dstRect.height),
-                "imgContainer::DrawFrameTo: Invalid aSrcRect");
+                "RasterImage::DrawFrameTo: Invalid aSrcRect");
 
     // clipped image size may be smaller than source, but not larger
     NS_ASSERTION((width <= aSrcRect.width) && (height <= aSrcRect.height),
-                 "imgContainer::DrawFrameTo: source must be smaller than dest");
+                 "RasterImage::DrawFrameTo: source must be smaller than dest");
 
     if (NS_FAILED(aDst->LockImageData()))
       return NS_ERROR_FAILURE;
 
     // Get pointers to image data
     PRUint32 size;
     PRUint8 *srcPixels;
     PRUint32 *colormap;
@@ -1966,77 +1969,82 @@ nsresult imgContainer::DrawFrameTo(imgFr
   aDst->GetSurface(getter_AddRefs(dstSurf));
 
   gfxContext dst(dstSurf);
   dst.Translate(gfxPoint(aSrcRect.x, aSrcRect.y));
   dst.Rectangle(gfxRect(0, 0, aSrcRect.width, aSrcRect.height), PR_TRUE);
   
   // first clear the surface if the blend flag says so
   PRInt32 blendMethod = aSrc->GetBlendMethod();
-  if (blendMethod == imgIContainer::kBlendSource) {
+  if (blendMethod == kBlendSource) {
     gfxContext::GraphicsOperator defaultOperator = dst.CurrentOperator();
     dst.SetOperator(gfxContext::OPERATOR_CLEAR);
     dst.Fill();
     dst.SetOperator(defaultOperator);
   }
   dst.SetPattern(srcPatt);
   dst.Paint();
 
   aDst->UnlockImageData();
 
   return NS_OK;
 }
 
 
 /********* Methods to implement lazy allocation of nsIProperties object *************/
-NS_IMETHODIMP imgContainer::Get(const char *prop, const nsIID & iid, void * *result)
+NS_IMETHODIMP
+RasterImage::Get(const char *prop, const nsIID & iid, void * *result)
 {
   if (!mProperties)
     return NS_ERROR_FAILURE;
   return mProperties->Get(prop, iid, result);
 }
 
-NS_IMETHODIMP imgContainer::Set(const char *prop, nsISupports *value)
+NS_IMETHODIMP
+RasterImage::Set(const char *prop, nsISupports *value)
 {
   if (!mProperties)
     mProperties = do_CreateInstance("@mozilla.org/properties;1");
   if (!mProperties)
     return NS_ERROR_OUT_OF_MEMORY;
   return mProperties->Set(prop, value);
 }
 
-NS_IMETHODIMP imgContainer::Has(const char *prop, PRBool *_retval)
+NS_IMETHODIMP
+RasterImage::Has(const char *prop, PRBool *_retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
   if (!mProperties) {
     *_retval = PR_FALSE;
     return NS_OK;
   }
   return mProperties->Has(prop, _retval);
 }
 
-NS_IMETHODIMP imgContainer::Undefine(const char *prop)
+NS_IMETHODIMP
+RasterImage::Undefine(const char *prop)
 {
   if (!mProperties)
     return NS_ERROR_FAILURE;
   return mProperties->Undefine(prop);
 }
 
-NS_IMETHODIMP imgContainer::GetKeys(PRUint32 *count, char ***keys)
+NS_IMETHODIMP
+RasterImage::GetKeys(PRUint32 *count, char ***keys)
 {
   if (!mProperties) {
     *count = 0;
     *keys = nsnull;
     return NS_OK;
   }
   return mProperties->GetKeys(count, keys);
 }
 
 void
-imgContainer::Discard()
+RasterImage::Discard()
 {
   // We should be ok for discard
   NS_ABORT_IF_FALSE(CanDiscard(), "Asked to discard but can't!");
 
   // We should never discard when we have an active decoder
   NS_ABORT_IF_FALSE(!mDecoder, "Asked to discard with open decoder!");
 
   // As soon as an image becomes animated, it becomes non-discardable and any
@@ -2057,58 +2065,58 @@ imgContainer::Discard()
   // Notify that we discarded
   nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
   if (observer)
     observer->OnDiscard(nsnull);
 
   // Log
   PR_LOG(gCompressedImageAccountingLog, PR_LOG_DEBUG,
          ("CompressedImageAccounting: discarded uncompressed image "
-          "data from imgContainer %p (%s) - %d frames (cached count: %d); "
+          "data from RasterImage %p (%s) - %d frames (cached count: %d); "
           "Total Containers: %d, Discardable containers: %d, "
           "Total source bytes: %lld, Source bytes for discardable containers %lld",
           this,
           mSourceDataMimeType.get(),
           old_frame_count,
           mFrames.Length(),
           num_containers,
           num_discardable_containers,
           total_source_bytes,
           discardable_source_bytes));
 }
 
 // Helper method to determine if we can discard an image
 PRBool
-imgContainer::CanDiscard() {
+RasterImage::CanDiscard() {
   return (DiscardingEnabled() && // Globally enabled...
           mDiscardable &&        // ...Enabled at creation time...
           (mLockCount == 0) &&   // ...not temporarily disabled...
           mHasSourceData &&      // ...have the source data...
           mDecoded);             // ...and have something to discard.
 }
 
 // Helper method to tell us whether the clock is currently running for
 // discarding this image. Mainly for assertions.
 PRBool
-imgContainer::DiscardingActive() {
+RasterImage::DiscardingActive() {
   return !!(mDiscardTrackerNode.prev || mDiscardTrackerNode.next);
 }
 
 // Helper method to determine if we're storing the source data in a buffer
 // or just writing it directly to the decoder
 PRBool
-imgContainer::StoringSourceData() {
+RasterImage::StoringSourceData() {
   return (mDecodeOnDraw || mDiscardable);
 }
 
 
 // Sets up a decoder for this image. It is an error to call this function
 // when decoding is already in process (ie - when mDecoder is non-null).
 nsresult
-imgContainer::InitDecoder (PRUint32 dFlags)
+RasterImage::InitDecoder(PRUint32 dFlags)
 {
   // Ensure that the decoder is not already initialized
   NS_ABORT_IF_FALSE(!mDecoder, "Calling InitDecoder() while already decoding!");
   
   // We shouldn't be firing up a decoder if we already have the frames decoded
   NS_ABORT_IF_FALSE(!mDecoded, "Calling InitDecoder() but already decoded!");
 
   // Since we're not decoded, we should not have a discard timer active
@@ -2139,17 +2147,17 @@ imgContainer::InitDecoder (PRUint32 dFla
 // state. It is an error to call this function when there is no initialized
 // decoder.
 // 
 // aIntent specifies the intent of the shutdown. If aIntent is
 // eShutdownIntent_Done, an error is flagged if we didn't get what we should
 // have out of the decode. If aIntent is eShutdownIntent_Interrupted, we don't
 // check this. If aIntent is eShutdownIntent_Error, we shut down in error mode.
 nsresult
-imgContainer::ShutdownDecoder(eShutdownIntent aIntent)
+RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
 {
   // Ensure that our intent is valid
   NS_ABORT_IF_FALSE((aIntent >= 0) || (aIntent < eShutdownIntent_AllCount),
                     "Invalid shutdown intent");
 
   // Ensure that the decoder is initialized
   NS_ABORT_IF_FALSE(mDecoder, "Calling ShutdownDecoder() with no active decoder!");
 
@@ -2207,17 +2215,17 @@ imgContainer::ShutdownDecoder(eShutdownI
   // Reset number of decoded bytes
   mBytesDecoded = 0;
 
   return NS_OK;
 }
 
 // Writes the data to the decoder, updating the total number of bytes written.
 nsresult
-imgContainer::WriteToDecoder(const char *aBuffer, PRUint32 aCount)
+RasterImage::WriteToDecoder(const char *aBuffer, PRUint32 aCount)
 {
   // We should have a decoder
   NS_ABORT_IF_FALSE(mDecoder, "Trying to write to null decoder!");
 
   // The decoder will start decoding into the current frame (if we have one).
   // When it needs to add another frame, we will unlock this frame and lock the
   // new frame.
   // Our invariant is that, while in the decoder, the last frame is always
@@ -2250,36 +2258,36 @@ imgContainer::WriteToDecoder(const char 
 
 // This function is called in situations where it's clear that we want the
 // frames in decoded form (Draw, GetFrame, CopyFrame, ExtractFrame, etc).
 // If we're completely decoded, this method resets the discard timer (if
 // we're discardable), since wanting the frames now is a good indicator of
 // wanting them again soon. If we're not decoded, this method kicks off
 // asynchronous decoding to generate the frames.
 nsresult
-imgContainer::WantDecodedFrames()
+RasterImage::WantDecodedFrames()
 {
   nsresult rv;
 
   // If we can discard, the clock should be running. Reset it.
   if (CanDiscard()) {
     NS_ABORT_IF_FALSE(DiscardingActive(),
                       "Decoded and discardable but discarding not activated!");
-    rv = imgDiscardTracker::Reset(&mDiscardTrackerNode);
+    rv = DiscardTracker::Reset(&mDiscardTrackerNode);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // Request a decode (no-op if we're decoded)
   return RequestDecode();
 }
 
 //******************************************************************************
 /* void requestDecode() */
 NS_IMETHODIMP
-imgContainer::RequestDecode()
+RasterImage::RequestDecode()
 {
   nsresult rv;
 
   if (mError)
     return NS_ERROR_FAILURE;
 
   // If we're not storing source data, we have nothing to do
   if (!StoringSourceData())
@@ -2331,17 +2339,17 @@ imgContainer::RequestDecode()
   // If we get this far, dispatch the worker. We do this instead of starting
   // any immediate decoding to guarantee that all our decode notifications are
   // dispatched asynchronously, and to ensure we stay responsive.
   return mWorker->Dispatch();
 }
 
 // Synchronously decodes as much data as possible
 nsresult
-imgContainer::SyncDecode()
+RasterImage::SyncDecode()
 {
   nsresult rv;
 
   // If we're decoded already, no worries
   if (mDecoded)
     return NS_OK;
 
   // If we're not storing source data, there isn't much to do here
@@ -2384,22 +2392,23 @@ imgContainer::SyncDecode()
 
 //******************************************************************************
 /* [noscript] void draw(in gfxContext aContext,
  *                      in gfxGraphicsFilter aFilter,
  *                      [const] in gfxMatrix aUserSpaceToImageSpace,
  *                      [const] in gfxRect aFill,
  *                      [const] in nsIntRect aSubimage,
  *                      in PRUint32 aFlags); */
-NS_IMETHODIMP imgContainer::Draw(gfxContext *aContext,
-                                 gfxPattern::GraphicsFilter aFilter,
-                                 const gfxMatrix &aUserSpaceToImageSpace,
-                                 const gfxRect &aFill,
-                                 const nsIntRect &aSubimage,
-                                 PRUint32 aFlags)
+NS_IMETHODIMP
+RasterImage::Draw(gfxContext *aContext,
+                  gfxPattern::GraphicsFilter aFilter,
+                  const gfxMatrix &aUserSpaceToImageSpace,
+                  const gfxRect &aFill,
+                  const nsIntRect &aSubimage,
+                  PRUint32 aFlags)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Disallowed in the API
   if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
     return NS_ERROR_FAILURE;
 
@@ -2424,34 +2433,34 @@ NS_IMETHODIMP imgContainer::Draw(gfxCont
   frame->Draw(aContext, aFilter, aUserSpaceToImageSpace, aFill, padding, aSubimage);
 
   return NS_OK;
 }
 
 //******************************************************************************
 /* void lockImage() */
 NS_IMETHODIMP
-imgContainer::LockImage()
+RasterImage::LockImage()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // Cancel the discard timer if it's there
-  imgDiscardTracker::Remove(&mDiscardTrackerNode);
+  DiscardTracker::Remove(&mDiscardTrackerNode);
 
   // Increment the lock count
   mLockCount++;
 
   return NS_OK;
 }
 
 //******************************************************************************
 /* void unlockImage() */
 NS_IMETHODIMP
-imgContainer::UnlockImage()
+RasterImage::UnlockImage()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   // It's an error to call this function if the lock count is 0
   NS_ABORT_IF_FALSE(mLockCount > 0,
                     "Calling UnlockImage with mLockCount == 0!");
   if (mLockCount == 0)
@@ -2460,26 +2469,26 @@ imgContainer::UnlockImage()
   // We're locked, so discarding should not be active
   NS_ABORT_IF_FALSE(!DiscardingActive(), "Locked, but discarding activated");
 
   // Decrement our lock count
   mLockCount--;
 
   // We now _might_ have one of the qualifications for discarding. Re-evaluate.
   if (CanDiscard()) {
-    nsresult rv = imgDiscardTracker::Reset(&mDiscardTrackerNode);
+    nsresult rv = DiscardTracker::Reset(&mDiscardTrackerNode);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   return NS_OK;
 }
 
 // Flushes up to aMaxBytes to the decoder.
 nsresult
-imgContainer::DecodeSomeData (PRUint32 aMaxBytes)
+RasterImage::DecodeSomeData(PRUint32 aMaxBytes)
 {
   // We should have a decoder if we get here
   NS_ABORT_IF_FALSE(mDecoder, "trying to decode without decoder!");
 
   // If we have nothing to decode, return
   if (mBytesDecoded == mSourceData.Length())
     return NS_OK;
 
@@ -2490,17 +2499,18 @@ imgContainer::DecodeSomeData (PRUint32 a
   nsresult rv = WriteToDecoder(mSourceData.Elements() + mBytesDecoded,
                                bytesToDecode);
 
   return rv;
 }
 
 // There are various indicators that tell us we're finished with the decode
 // task at hand and can shut down the decoder.
-PRBool imgContainer::IsDecodeFinished()
+PRBool
+RasterImage::IsDecodeFinished()
 {
   // Assume it's not finished
   PRBool decodeFinished = PR_FALSE;
 
   // There shouldn't be any reason to call this if we're not storing
   // source data
   NS_ABORT_IF_FALSE(StoringSourceData(),
                     "just shut down on SourceDataComplete!");
@@ -2523,17 +2533,18 @@ PRBool imgContainer::IsDecodeFinished()
   if (mHasSourceData && (mBytesDecoded == mSourceData.Length()))
     decodeFinished = PR_TRUE;
 
   return decodeFinished;
 }
 
 // Indempotent error flagging routine. If a decoder is open,
 // sends OnStopContainer and OnStopDecode and shuts down the decoder
-void imgContainer::DoError()
+void
+RasterImage::DoError()
 {
   // If we've flagged an error before, we have nothing to do
   if (mError)
     return;
 
   // If we're mid-decode
   if (mDecoder) {
 
@@ -2557,128 +2568,135 @@ void imgContainer::DoError()
 }
 
 // Tweakable progressive decoding parameters
 #define DECODE_BYTES_AT_A_TIME 4096
 #define MAX_USEC_BEFORE_YIELD (1000 * 5)
 
 // Decodes some data, then re-posts itself to the end of the event queue if
 // there's more processing to be done
-NS_IMETHODIMP imgDecodeWorker::Run()
+NS_IMETHODIMP
+imgDecodeWorker::Run()
 {
   nsresult rv;
 
   // If we shutdown the decoder in this function, we could lose ourselves
   nsCOMPtr<nsIRunnable> kungFuDeathGrip(this);
 
   // The container holds a strong reference to us. Cycles are bad.
   nsCOMPtr<imgIContainer> iContainer(do_QueryReferent(mContainer));
   if (!iContainer)
     return NS_OK;
-  imgContainer* container = static_cast<imgContainer*>(iContainer.get());
-
-  NS_ABORT_IF_FALSE(container->mInitialized,
+  RasterImage* image = static_cast<RasterImage*>(iContainer.get());
+
+  NS_ABORT_IF_FALSE(image->mInitialized,
                     "Worker active for uninitialized container!");
 
   // If we were pending, we're not anymore
-  container->mWorkerPending = PR_FALSE;
+  image->mWorkerPending = PR_FALSE;
 
   // If an error is flagged, it probably happened while we were waiting
   // in the event queue. Bail early, but no need to bother the run queue
   // by returning an error.
-  if (container->mError)
+  if (image->mError)
     return NS_OK;
 
   // If we don't have a decoder, we must have finished already (for example,
   // a synchronous decode request came while the worker was pending).
-  if (!container->mDecoder)
+  if (!image->mDecoder)
     return NS_OK;
 
   // Header-only decodes are cheap and we more or less want them to be
   // synchronous. Write all the data in that case, otherwise write a
   // chunk
   PRUint32 maxBytes =
-    (container->mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
-    ? container->mSourceData.Length() : DECODE_BYTES_AT_A_TIME;
+    (image->mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
+    ? image->mSourceData.Length() : DECODE_BYTES_AT_A_TIME;
 
   // Loop control
   PRBool haveMoreData = PR_TRUE;
   nsTime deadline(PR_Now() + MAX_USEC_BEFORE_YIELD);
 
   // We keep decoding chunks until one of three possible events occur:
   // 1) We don't have any data left to decode
   // 2) The decode completes
   // 3) We hit the deadline and need to yield to keep the UI snappy
-  while (haveMoreData && !container->IsDecodeFinished() &&
+  while (haveMoreData && !image->IsDecodeFinished() &&
          (nsTime(PR_Now()) < deadline)) {
 
     // Decode a chunk of data
-    rv = container->DecodeSomeData(maxBytes);
+    rv = image->DecodeSomeData(maxBytes);
     if (NS_FAILED(rv)) {
-      container->DoError();
+      image->DoError();
       return rv;
     }
 
     // Figure out if we still have more data
     haveMoreData =
-      container->mSourceData.Length() > container->mBytesDecoded;
+      image->mSourceData.Length() > image->mBytesDecoded;
   }
 
   // If the decode finished, shutdown the decoder
-  if (container->IsDecodeFinished()) {
-    rv = container->ShutdownDecoder(imgContainer::eShutdownIntent_Done);
+  if (image->IsDecodeFinished()) {
+    rv = image->ShutdownDecoder(RasterImage::eShutdownIntent_Done);
     if (NS_FAILED(rv)) {
-      container->DoError();
+      image->DoError();
       return rv;
     }
   }
 
   // If Conditions 1 & 2 are still true, then the only reason we bailed was
   // because we hit the deadline. Repost ourselves to the end of the event
   // queue.
-  if (!container->IsDecodeFinished() && haveMoreData)
+  if (!image->IsDecodeFinished() && haveMoreData)
     return this->Dispatch();
 
   // Otherwise, return success
   return NS_OK;
 }
 
 // Queues the worker up at the end of the event queue
 NS_METHOD imgDecodeWorker::Dispatch()
 {
   // The container holds a strong reference to us. Cycles are bad.
   nsCOMPtr<imgIContainer> iContainer(do_QueryReferent(mContainer));
   if (!iContainer)
     return NS_OK;
-  imgContainer* container = static_cast<imgContainer*>(iContainer.get());
+  RasterImage* image = static_cast<RasterImage*>(iContainer.get());
 
   // We should not be called if there's already a pending worker
-  NS_ABORT_IF_FALSE(!container->mWorkerPending,
+  NS_ABORT_IF_FALSE(!image->mWorkerPending,
                     "Trying to queue up worker with one already pending!");
 
   // Flag that we're pending
-  container->mWorkerPending = PR_TRUE;
+  image->mWorkerPending = PR_TRUE;
 
   // Dispatch
   return NS_DispatchToCurrentThread(this);
 }
 
 // nsIInputStream callback to copy the incoming image data directly to the 
-// container without processing. The imgContainer is passed as the closure.
+// RasterImage without processing. The RasterImage is passed as the closure.
 // Always reads everything it gets, even if the data is erroneous.
 NS_METHOD
-imgContainer::WriteToContainer(nsIInputStream* in, void* closure,
-                               const char* fromRawSegment, PRUint32 toOffset,
-                               PRUint32 count, PRUint32 *writeCount)
+RasterImage::WriteToRasterImage(nsIInputStream* /* unused */,
+                                void*          aClosure,
+                                const char*    aFromRawSegment,
+                                PRUint32       /* unused */,
+                                PRUint32       aCount,
+                                PRUint32*      aWriteCount)
 {
-  // Retrieve the imgContainer
-  imgIContainer *container = static_cast<imgIContainer*>(closure);
+  // Retrieve the RasterImage
+  RasterImage* image = static_cast<RasterImage*>(aClosure);
 
   // Copy the source data. We squelch the return value here, because returning
   // an error means that ReadSegments stops reading data, violating our
   // invariant that we read everything we get.
-  (void) container->AddSourceData(fromRawSegment, count);
+  (void) image->AddSourceData(aFromRawSegment, aCount);
 
   // We wrote everything we got
-  *writeCount = count;
+  *aWriteCount = aCount;
 
   return NS_OK;
 }
+
+} // namespace imagelib
+} // namespace mozilla
rename from modules/libpr0n/src/imgContainer.h
rename to modules/libpr0n/src/RasterImage.h
--- a/modules/libpr0n/src/imgContainer.h
+++ b/modules/libpr0n/src/RasterImage.h
@@ -36,56 +36,58 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /** @file
- * This file declares the imgContainer class, which
- * handles static and animated image containers.
+ * This file declares the RasterImage class, which
+ * handles static and animated rasterized images.
  *
  * @author  Stuart Parmenter <pavlov@netscape.com>
  * @author  Chris Saari <saari@netscape.com>
  * @author  Arron Mogge <paper@animecity.nu>
  * @author  Andrew Smith <asmith15@learn.senecac.on.ca>
  */
 
-#ifndef __imgContainer_h__
-#define __imgContainer_h__
+#ifndef mozilla_imagelib_RasterImage_h_
+#define mozilla_imagelib_RasterImage_h_
 
+#include "Image.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "imgIContainer.h"
-#include "imgIDecoder.h"
 #include "nsIProperties.h"
 #include "nsITimer.h"
 #include "nsWeakReference.h"
 #include "nsTArray.h"
 #include "imgFrame.h"
 #include "nsThreadUtils.h"
-#include "imgDiscardTracker.h"
-#include "imgStatusTracker.h"
+#include "DiscardTracker.h"
 
-#define NS_IMGCONTAINER_CID \
+class imgIDecoder;
+class nsIInputStream;
+
+#define NS_RASTERIMAGE_CID \
 { /* 376ff2c1-9bf6-418a-b143-3340c00112f7 */         \
      0x376ff2c1,                                     \
      0x9bf6,                                         \
      0x418a,                                         \
     {0xb1, 0x43, 0x33, 0x40, 0xc0, 0x01, 0x12, 0xf7} \
 }
 
 /**
  * Handles static and animated image containers.
  *
  *
  * @par A Quick Walk Through
  * The decoder initializes this class and calls AppendFrame() to add a frame.
- * Once imgContainer detects more than one frame, it starts the animation
+ * Once RasterImage detects more than one frame, it starts the animation
  * with StartAnimation().
  *
  * @par
  * StartAnimation() checks if animating is allowed, and creates a timer.  The
  * timer calls Notify when the specified frame delay time is up.
  *
  * @par
  * Notify() moves on to the next frame, sets up the new timer delay, destroys
@@ -100,22 +102,22 @@
  * The basic path through DoComposite() is:
  * 1) Calculate Area that needs updating, which is at least the area of
  *    aNextFrame.
  * 2) Dispose of previous frame.
  * 3) Draw new image onto compositingFrame.
  * See comments in DoComposite() for more information and optimizations.
  *
  * @par
- * The rest of the imgContainer specific functions are used by DoComposite to
+ * The rest of the RasterImage specific functions are used by DoComposite to
  * destroy the old frame and build the new one.
  *
  * @note
  * <li> "Mask", "Alpha", and "Alpha Level" are interchangeable phrases in
- * respects to imgContainer.
+ * respects to RasterImage.
  *
  * @par
  * <li> GIFs never have more than a 1 bit alpha.
  * <li> APNGs may have a full alpha channel.
  *
  * @par
  * <li> Background color specified in GIF is ignored by web browsers.
  *
@@ -131,44 +133,161 @@
  * The mAnim structure has members only needed for animated images, so
  * it's not allocated until the second frame is added.
  *
  * @note
  * mAnimationMode, mLoopCount and mObserver are not in the mAnim structure
  * because the first two have public setters and the observer we only get
  * in Init().
  */
+
+namespace mozilla {
+namespace imagelib {
+
 class imgDecodeWorker;
-class imgContainer : public imgIContainer, 
-                     public nsITimerCallback,
-                     public nsIProperties,
-                     public nsSupportsWeakReference
+
+class RasterImage : public mozilla::imagelib::Image,
+                    public nsITimerCallback,
+                    public nsIProperties,
+                    public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGICONTAINER
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIPROPERTIES
 
-  imgContainer();
-  virtual ~imgContainer();
+  RasterImage();
+  virtual ~RasterImage();
+
+  // C++-only version of imgIContainer::GetType, for convenience
+  virtual PRUint16 GetType() { return imgIContainer::TYPE_RASTER; }
 
-  static NS_METHOD WriteToContainer(nsIInputStream* in, void* closure,
-                                    const char* fromRawSegment,
-                                    PRUint32 toOffset, PRUint32 count,
-                                    PRUint32 *writeCount);
+  // Methods inherited from Image
+  nsresult Init(imgIDecoderObserver *aObserver,
+                const char* aMimeType,
+                PRUint32 aFlags);
+  nsresult GetCurrentFrameRect(nsIntRect& aRect);
+  nsresult GetCurrentFrameIndex(PRUint32* aCurrentFrameIdx);
+  nsresult GetNumFrames(PRUint32* aNumFrames);
+  nsresult GetDataSize(PRUint32* aDataSize);
+
+  // Raster-specific methods
+  static NS_METHOD WriteToRasterImage(nsIInputStream* aIn, void* aClosure,
+                                      const char* aFromRawSegment,
+                                      PRUint32 aToOffset, PRUint32 aCount,
+                                      PRUint32* aWriteCount);
 
   PRUint32 GetDecodedDataSize();
   PRUint32 GetSourceDataSize();
 
   /* Triggers discarding. */
   void Discard();
 
-  imgStatusTracker& GetStatusTracker() { return mStatusTracker; }
-  PRBool IsInitialized() const { return mInitialized; }
+  /* Callbacks for decoders */
+  nsresult SetFrameDisposalMethod(PRUint32 aFrameNum,
+                                  PRInt32 aDisposalMethod);
+  nsresult SetFrameTimeout(PRUint32 aFrameNum, PRInt32 aTimeout);
+  nsresult SetFrameBlendMethod(PRUint32 aFrameNum, PRInt32 aBlendMethod);
+  nsresult SetFrameHasNoAlpha(PRUint32 aFrameNum);
+
+  /**
+   * Sets the size of the container. This should only be called by the
+   * decoder. This function may be called multiple times, but will throw an
+   * error if subsequent calls do not match the first.
+   */
+  nsresult SetSize(PRInt32 aWidth, PRInt32 aHeight);
+
+  nsresult EnsureCleanFrame(PRUint32 aFramenum, PRInt32 aX, PRInt32 aY,
+                            PRInt32 aWidth, PRInt32 aHeight,
+                            gfxASurface::gfxImageFormat aFormat,
+                            PRUint8** imageData,
+                            PRUint32* imageLength);
+
+  /**
+   * Adds to the end of the list of frames.
+   */
+  nsresult AppendFrame(PRInt32 aX, PRInt32 aY,
+                       PRInt32 aWidth, PRInt32 aHeight,
+                       gfxASurface::gfxImageFormat aFormat,
+                       PRUint8** imageData,
+                       PRUint32* imageLength);
+
+  nsresult AppendPalettedFrame(PRInt32 aX, PRInt32 aY,
+                               PRInt32 aWidth, PRInt32 aHeight,
+                               gfxASurface::gfxImageFormat aFormat,
+                               PRUint8 aPaletteDepth,
+                               PRUint8**  imageData,
+                               PRUint32*  imageLength,
+                               PRUint32** paletteData,
+                               PRUint32*  paletteLength);
+
+  nsresult FrameUpdated(PRUint32 aFrameNum, nsIntRect& aUpdatedRect);
+
+  /* notification when the current frame is done decoding */
+  nsresult EndFrameDecode(PRUint32 aFrameNum);
+
+  /* notification that the entire image has been decoded */
+  nsresult DecodingComplete();
+
+  /**
+   * Number of times to loop the image.
+   * @note -1 means forever.
+   */
+  void     SetLoopCount(PRInt32 aLoopCount);
+
+  /* Add compressed source data to the imgContainer.
+   *
+   * The decoder will use this data, either immediately or at draw time, to
+   * decode the image.
+   *
+   * XXX This method's only caller (WriteToContainer) ignores the return
+   * value. Should this just return void?
+   */
+  nsresult AddSourceData(const char *aBuffer, PRUint32 aCount);
+
+  /* Called after the all the source data has been added with addSourceData. */
+  virtual nsresult SourceDataComplete();
+
+  /* Called for multipart images when there's a new source image to add. */
+  virtual nsresult NewSourceData();
+
+  /**
+   * A hint of the number of bytes of source data that the image contains. If
+   * called early on, this can help reduce copying and reallocations by
+   * appropriately preallocating the source data buffer.
+   *
+   * We take this approach rather than having the source data management code do
+   * something more complicated (like chunklisting) because HTTP is by far the
+   * dominant source of images, and the Content-Length header is quite reliable.
+   * Thus, pre-allocation simplifies code and reduces the total number of
+   * allocations.
+   */
+  virtual nsresult SetSourceSizeHint(PRUint32 sizeHint);
+
+  // "Blend" method indicates how the current image is combined with the
+  // previous image.
+  enum {
+    // All color components of the frame, including alpha, overwrite the current
+    // contents of the frame's output buffer region
+    kBlendSource =  0,
+
+    // The frame should be composited onto the output buffer based on its alpha,
+    // using a simple OVER operation
+    kBlendOver
+  };
+
+  enum {
+    kDisposeClearAll         = -1, // Clear the whole image, revealing
+                                   // what was there before the gif displayed
+    kDisposeNotSpecified,   // Leave frame, let new frame draw on top
+    kDisposeKeep,           // Leave frame, let new frame draw on top
+    kDisposeClear,          // Clear the frame's area, revealing bg
+    kDisposeRestorePrevious // Restore the previous (composited) frame
+  };
 
 private:
   struct Anim
   {
     //! Area of the first frame that needs to be redrawn on subsequent loops.
     nsIntRect                  firstFrameRefreshArea;
     // Note this doesn't hold a proper value until frame 2 finished decoding.
     PRUint32                   currentDecodingFrameIndex; // 0 to numFrames-1
@@ -311,51 +430,48 @@ private: // data
   // memory, or we may be decoding on draw).
   nsTArray<imgFrame *>       mFrames;
   
   nsCOMPtr<nsIProperties>    mProperties;
 
   // IMPORTANT: if you use mAnim in a method, call EnsureImageIsDecoded() first to ensure
   // that the frames actually exist (they may have been discarded to save memory, or
   // we maybe decoding on draw).
-  imgContainer::Anim*        mAnim;
+  RasterImage::Anim*        mAnim;
   
   //! See imgIContainer for mode constants
   PRUint16                   mAnimationMode;
   
   //! # loops remaining before animation stops (-1 no stop)
   PRInt32                    mLoopCount;
   
   //! imgIDecoderObserver
   nsWeakPtr                  mObserver;
 
   // Discard members
   PRUint32                   mLockCount;
-  imgDiscardTrackerNode      mDiscardTrackerNode;
+  DiscardTrackerNode         mDiscardTrackerNode;
 
   // Source data members
   nsTArray<char>             mSourceData;
   nsCString                  mSourceDataMimeType;
 
-  imgStatusTracker    mStatusTracker;
-
   friend class imgDecodeWorker;
-  friend class imgDiscardTracker;
+  friend class DiscardTracker;
 
   // Decoder and friends
   nsCOMPtr<imgIDecoder>          mDecoder;
   nsRefPtr<imgDecodeWorker>      mWorker;
   PRUint32                       mBytesDecoded;
   PRUint32                       mDecoderFlags;
 
   // Boolean flags (clustered together to conserve space):
   PRPackedBool               mHasSize:1;       // Has SetSize() been called?
   PRPackedBool               mDecodeOnDraw:1;  // Decoding on draw?
   PRPackedBool               mMultipart:1;     // Multipart?
-  PRPackedBool               mInitialized:1;   // Have we been initalized?
   PRPackedBool               mDiscardable:1;   // Is container discardable?
   PRPackedBool               mHasSourceData:1; // Do we have source data?
 
   // Do we have the frames in decoded form?
   PRPackedBool               mDecoded:1;
   PRPackedBool               mHasBeenDecoded:1;
 
   // Helpers for decoder
@@ -384,16 +500,18 @@ private: // data
   // Helpers
   void DoError();
   PRBool CanDiscard();
   PRBool DiscardingActive();
   PRBool StoringSourceData();
 
 };
 
+// XXXdholbert These helper classes should move to be inside the
+// scope of the RasterImage class.
 // Decoding Helper Class
 //
 // We use this class to mimic the interactivity benefits of threading
 // in a single-threaded event loop. We want to progressively decode
 // and keep a responsive UI while we're at it, so we have a runnable
 // class that does a bit of decoding, and then "yields" by dispatching
 // itself to the end of the event queue.
 class imgDecodeWorker : public nsRunnable
@@ -427,11 +545,12 @@ class imgDecodeRequestor : public nsRunn
         con->RequestDecode();
       return NS_OK;
     }
 
   private:
     nsWeakPtr mContainer;
 };
 
-
+} // namespace imagelib
+} // namespace mozilla
 
-#endif /* __imgContainer_h__ */
+#endif /* mozilla_imagelib_RasterImage_h_ */
--- a/modules/libpr0n/src/imgLoader.cpp
+++ b/modules/libpr0n/src/imgLoader.cpp
@@ -34,18 +34,26 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "imgLoader.h"
-#include "imgContainer.h"
+#include "imgRequestProxy.h"
 
+#include "RasterImage.h"
+/* We end up pulling in windows.h because we eventually hit gfxWindowsSurface;
+ * windows.h defines LoadImage, so we have to #undef it or imgLoader::LoadImage
+ * gets changed.
+ * This #undef needs to be in multiple places because we don't always pull
+ * headers in in the same order.
+ */
+#undef LoadImage
 
 #include "nsCOMPtr.h"
 
 #include "nsNetUtil.h"
 #include "nsIHttpChannel.h"
 #include "nsICachingChannel.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIPrefBranch2.h"
@@ -57,19 +65,16 @@
 #include "nsIServiceManager.h"
 #include "nsIFileURL.h"
 #include "nsThreadUtils.h"
 #include "nsXPIDLString.h"
 #include "nsCRT.h"
 
 #include "netCore.h"
 
-#include "imgRequest.h"
-#include "imgRequestProxy.h"
-
 #include "nsURILoader.h"
 #include "ImageLogging.h"
 
 #include "nsIComponentRegistrar.h"
 
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheContainer.h"
 
@@ -80,23 +85,26 @@
 // so we can associate the document URI with the load group.
 // until this point, we have an evil hack:
 #include "nsIHttpChannelInternal.h"  
 #include "nsIContentSecurityPolicy.h"
 #include "nsIChannelPolicy.h"
 
 #include "mozilla/FunctionTimer.h"
 
+using namespace mozilla::imagelib;
+
 #if defined(DEBUG_pavlov) || defined(DEBUG_timeless)
 #include "nsISimpleEnumerator.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsXPIDLString.h"
 #include "nsComponentManagerUtils.h"
 
+
 static void PrintImageDecoders()
 {
   nsCOMPtr<nsIComponentRegistrar> compMgr;
   if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr)
     return;
   nsCOMPtr<nsISimpleEnumerator> enumer;
   if (NS_FAILED(compMgr->EnumerateContractIDs(getter_AddRefs(enumer))) || !enumer)
     return;
@@ -212,24 +220,24 @@ public:
       if (entry->HasNoProxies())
         return PL_DHASH_NEXT;
     } else {
       if (!entry->HasNoProxies())
         return PL_DHASH_NEXT;
     }
 
     nsRefPtr<imgRequest> req = entry->GetRequest();
-    imgContainer *container = (imgContainer*) req->mImage.get();
-    if (!container)
+    RasterImage *image = static_cast<RasterImage*>(req->mImage.get());
+    if (!image)
       return PL_DHASH_NEXT;
 
     if (rtype & RAW_BIT) {
-      arg->value += container->GetSourceDataSize();
+      arg->value += image->GetSourceDataSize();
     } else {
-      arg->value += container->GetDecodedDataSize();
+      arg->value += image->GetDecodedDataSize();
     }
 
     return PL_DHASH_NEXT;
   }
 
   NS_IMETHOD GetMemoryUsed(PRInt64 *memoryUsed)
   {
     EnumArg arg(mType);
--- a/modules/libpr0n/src/imgLoader.h
+++ b/modules/libpr0n/src/imgLoader.h
@@ -33,40 +33,35 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifndef imgLoader_h__
+#define imgLoader_h__
+
 #include "imgILoader.h"
 #include "imgICache.h"
 #include "nsWeakReference.h"
 #include "nsIContentSniffer.h"
 #include "nsRefPtrHashtable.h"
 #include "nsExpirationTracker.h"
 #include "nsAutoPtr.h"
 #include "prtypes.h"
 #include "imgRequest.h"
 #include "nsIObserverService.h"
 #include "nsIChannelPolicy.h"
 
 #ifdef LOADER_THREADSAFE
 #include "prlock.h"
 #endif
 
-/* We end up pulling in windows.h because we eventually hit gfxWindowsSurface;
- * windows.h defines LoadImage, so we have to #undef it or imgLoader::LoadImage
- * gets changed.
- * This #undef needs to be in multiple places because we don't always pull
- * headers in in the same order.
- */
-#undef LoadImage
-
 class imgRequest;
 class imgRequestProxy;
 class imgIRequest;
 class imgIDecoderObserver;
 class nsILoadGroup;
 class nsIPrefBranch;
 
 class imgCacheEntry
@@ -405,8 +400,10 @@ private:
 
   nsRefPtr<imgRequest> mRequest;
   nsCOMArray<imgIRequest> mProxies;
 
   void *mContext;
 
   static imgLoader sImgLoader;
 };
+
+#endif  // imgLoader_h__
--- a/modules/libpr0n/src/imgRequest.cpp
+++ b/modules/libpr0n/src/imgRequest.cpp
@@ -45,17 +45,17 @@
  * gets changed.
  * This #undef needs to be in multiple places because we don't always pull
  * headers in in the same order.
  */
 #undef LoadImage
 
 #include "imgLoader.h"
 #include "imgRequestProxy.h"
-#include "imgContainer.h"
+#include "RasterImage.h"
 
 #include "imgILoader.h"
 #include "ImageLogging.h"
 
 #include "netCore.h"
 
 #include "nsIChannel.h"
 #include "nsICachingChannel.h"
@@ -77,21 +77,24 @@
 #include "nsXPIDLString.h"
 #include "plstr.h" // PL_strcasestr(...)
 #include "nsNetUtil.h"
 #include "nsIProtocolHandler.h"
 
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 
-#include "imgDiscardTracker.h"
+#include "DiscardTracker.h"
 #include "nsAsyncRedirectVerifyHelper.h"
 
 #define DISCARD_PREF "image.mem.discardable"
 #define DECODEONDRAW_PREF "image.mem.decodeondraw"
+#define SVG_MIMETYPE "image/svg+xml"
+
+using namespace mozilla::imagelib;
 
 /* Kept up to date by a pref observer. */
 static PRBool gDecodeOnDraw = PR_FALSE;
 static PRBool gDiscardable = PR_FALSE;
 
 /*
  * Pref observer goop. Yuck.
  */
@@ -111,17 +114,17 @@ ReloadPrefs(nsIPrefBranch *aBranch)
 
   // Decode-on-draw
   PRBool decodeondraw;
   rv = aBranch->GetBoolPref(DECODEONDRAW_PREF, &decodeondraw);
   if (NS_SUCCEEDED(rv))
     gDecodeOnDraw = decodeondraw;
 
   // Discard timeout
-  imgDiscardTracker::ReloadTimeout();
+  mozilla::imagelib::DiscardTracker::ReloadTimeout();
 }
 
 // Observer
 class imgRequestPrefObserver : public nsIObserver {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
 };
@@ -195,18 +198,21 @@ nsresult imgRequest::Init(nsIURI *aURI,
 
   NS_ABORT_IF_FALSE(!mImage, "Multiple calls to init");
   NS_ABORT_IF_FALSE(aURI, "No uri");
   NS_ABORT_IF_FALSE(aKeyURI, "No key uri");
   NS_ABORT_IF_FALSE(aRequest, "No request");
   NS_ABORT_IF_FALSE(aChannel, "No channel");
 
   mProperties = do_CreateInstance("@mozilla.org/properties;1");
-  nsCOMPtr<imgIContainer> comImg = do_CreateInstance("@mozilla.org/image/container;3");
-  mImage = static_cast<imgContainer*>(comImg.get());
+
+  // XXXdholbert For SVG support, this mImage-construction will need to happen
+  // later -- *after* we know image mimetype.
+  nsCOMPtr<imgIContainer> comImg = do_CreateInstance("@mozilla.org/image/rasterimage;1");
+  mImage = static_cast<Image*>(comImg.get());
 
   mURI = aURI;
   mKeyURI = aKeyURI;
   mRequest = aRequest;
   mChannel = aChannel;
   mChannel->GetNotificationCallbacks(getter_AddRefs(mPrevChannelSink));
 
   NS_ASSERTION(mPrevChannelSink != this,
@@ -329,16 +335,22 @@ nsresult imgRequest::RemoveProxy(imgRequ
   // If a proxy is removed for a reason other than its owner being
   // changed, remove the proxy from the loadgroup.
   if (aStatus != NS_IMAGELIB_CHANGING_OWNER)
     proxy->RemoveFromLoadGroup(PR_TRUE);
 
   return NS_OK;
 }
 
+PRBool imgRequest::IsReusable(void *aCacheId)
+{
+  return (mImage && mImage->GetStatusTracker().IsLoading()) ||
+    (aCacheId == mCacheId);
+}
+
 void imgRequest::CancelAndAbort(nsresult aStatus)
 {
   LOG_SCOPE(gImgLog, "imgRequest::CancelAndAbort");
 
   Cancel(aStatus);
 
   // It's possible for the channel to fail to open after we've set our
   // notification callbacks. In that case, make sure to break the cycle between
@@ -507,17 +519,17 @@ imgRequest::RequestDecode()
 
   return NS_OK;
 }
 
 /** imgIContainerObserver methods **/
 
 /* [noscript] void frameChanged (in imgIContainer container, in nsIntRect dirtyRect); */
 NS_IMETHODIMP imgRequest::FrameChanged(imgIContainer *container,
-                                       nsIntRect * dirtyRect)
+                                       const nsIntRect *dirtyRect)
 {
   LOG_SCOPE(gImgLog, "imgRequest::FrameChanged");
 
   mImage->GetStatusTracker().RecordFrameChanged(container, dirtyRect);
 
   nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
   while (iter.HasMore()) {
     mImage->GetStatusTracker().SendFrameChanged(iter.GetNext(), container, dirtyRect);
@@ -654,26 +666,26 @@ NS_IMETHODIMP imgRequest::OnStopDecode(i
   mImage->GetStatusTracker().RecordStopDecode(aStatus, aStatusArg);
 
   nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
   while (iter.HasMore()) {
     mImage->GetStatusTracker().SendStopDecode(iter.GetNext(), aStatus,
                                               aStatusArg);
   }
 
-  // ImgContainer and everything below it is completely correct and
+  // 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 container and generate our own every time we send
+  // 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;
 }
 
 NS_IMETHODIMP imgRequest::OnStopRequest(imgIRequest *aRequest,
                                         PRBool aLastPart)
@@ -712,20 +724,20 @@ NS_IMETHODIMP imgRequest::OnStartRequest
   if (mpchan)
       mIsMultiPartChannel = PR_TRUE;
 
   // If we're not multipart, we shouldn't have an image yet
   NS_ABORT_IF_FALSE(mIsMultiPartChannel || !mImage->IsInitialized(),
                     "Already have an image for non-multipart request");
 
   // If we're multipart, and our image is initialized, fix things up for another round
-  if (mIsMultiPartChannel && mImage->IsInitialized()) {
-
-    // Inform the container that we have new source data
-    mImage->NewSourceData();
+  if (mIsMultiPartChannel && mImage->IsInitialized() &&
+      mImage->GetType() == imgIContainer::TYPE_RASTER) {
+    // Inform the RasterImage that we have new source data
+    static_cast<RasterImage*>(mImage.get())->NewSourceData();
   }
 
   /*
    * If mRequest is null here, then we need to set it so that we'll be able to
    * cancel it if our Cancel() method is called.  Note that this can only
    * happen for multipart channels.  We could simply not null out mRequest for
    * non-last parts, if GetIsLastPart() were reliable, but it's not.  See
    * https://bugzilla.mozilla.org/show_bug.cgi?id=339610
@@ -850,20 +862,21 @@ NS_IMETHODIMP imgRequest::OnStopRequest(
     mChannel->SetNotificationCallbacks(mPrevChannelSink);
     mPrevChannelSink = nsnull;
     mChannel = nsnull;
   }
 
   // Tell the image that it has all of the source data. Note that this can
   // trigger a failure, since the image might be waiting for more non-optional
   // data and this is the point where we break the news that it's not coming.
-  if (mImage->IsInitialized()) {
+  if (mImage->IsInitialized() &&
+      mImage->GetType() == imgIContainer::TYPE_RASTER) {
 
     // Notify the image
-    nsresult rv = mImage->SourceDataComplete();
+    nsresult rv = static_cast<RasterImage*>(mImage.get())->SourceDataComplete();
 
     // If we got an error in the SourceDataComplete() call, we don't want to
     // proceed as if nothing bad happened. However, we also want to give
     // precedence to failure status codes from necko, since presumably
     // they're more meaningful.
     if (NS_FAILED(rv) && NS_SUCCEEDED(status))
       status = rv;
   }
@@ -901,17 +914,20 @@ static NS_METHOD sniff_mimetype_callback
 NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
 {
   LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "count", count);
 
   NS_ASSERTION(aRequest, "imgRequest::OnDataAvailable -- no request!");
 
   nsresult rv;
 
-  if (!mGotData) {
+  PRUint16 imageType;
+  if (mGotData) {
+    imageType = mImage->GetType();
+  } else {
     LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable |First time through... finding mimetype|");
 
     mGotData = PR_TRUE;
 
     /* look at the first few bytes and see if we can tell what the data is from that
      * since servers tend to lie. :(
      */
     PRUint32 out;
@@ -939,16 +955,20 @@ NS_IMETHODIMP imgRequest::OnDataAvailabl
         this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
 
         return NS_BINDING_ABORTED;
       }
 
       LOG_MSG(gImgLog, "imgRequest::OnDataAvailable", "Got content type from the channel");
     }
 
+    /* now we have mimetype, so we can infer the image type that we want */
+    imageType = mContentType.EqualsLiteral(SVG_MIMETYPE) ?
+      imgIContainer::TYPE_VECTOR : imgIContainer::TYPE_RASTER;
+
     /* set our mimetype as a property */
     nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1"));
     if (contentType) {
       contentType->SetData(mContentType);
       mProperties->Set("type", contentType);
     }
 
     /* set our content disposition as a property */
@@ -968,17 +988,17 @@ NS_IMETHODIMP imgRequest::OnDataAvailabl
         contentDisposition->SetData(disposition);
         mProperties->Set("content-disposition", contentDisposition);
       }
     }
 
     LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "content type", mContentType.get());
 
     //
-    // Figure out if our container initialization flags
+    // Figure out our Image initialization flags
     //
 
     // We default to the static globals
     PRBool isDiscardable = gDiscardable;
     PRBool doDecodeOnDraw = gDecodeOnDraw;
 
     // We want UI to be as snappy as possible and not to flicker. Disable discarding
     // and decode-on-draw for chrome URLS
@@ -995,71 +1015,74 @@ NS_IMETHODIMP imgRequest::OnDataAvailabl
       isDiscardable = doDecodeOnDraw = PR_FALSE;
 
     // For multipart/x-mixed-replace, we basically want a direct channel to the
     // decoder. Disable both for this case as well.
     if (mIsMultiPartChannel)
       isDiscardable = doDecodeOnDraw = PR_FALSE;
 
     // We have all the information we need
-    PRUint32 containerFlags = imgIContainer::INIT_FLAG_NONE;
+    PRUint32 imageFlags = Image::INIT_FLAG_NONE;
     if (isDiscardable)
-      containerFlags |= imgIContainer::INIT_FLAG_DISCARDABLE;
+      imageFlags |= Image::INIT_FLAG_DISCARDABLE;
     if (doDecodeOnDraw)
-      containerFlags |= imgIContainer::INIT_FLAG_DECODE_ON_DRAW;
+      imageFlags |= Image::INIT_FLAG_DECODE_ON_DRAW;
     if (mIsMultiPartChannel)
-      containerFlags |= imgIContainer::INIT_FLAG_MULTIPART;
+      imageFlags |= Image::INIT_FLAG_MULTIPART;
 
     // Initialize the image that we created in OnStartRequest(). This
     // instantiates a decoder behind the scenes, so if we don't have a decoder
     // for this mimetype we'll find out about it here.
-    rv = mImage->Init(this, mContentType.get(), containerFlags);
+    rv = mImage->Init(this, mContentType.get(), imageFlags);
     if (NS_FAILED(rv)) { // Probably bad mimetype
 
       this->Cancel(rv);
       return NS_BINDING_ABORTED;
     }
 
-    /* Use content-length as a size hint for http channels. */
-    if (httpChannel) {
-      nsCAutoString contentLength;
-      rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-length"),
-                                          contentLength);
-      if (NS_SUCCEEDED(rv)) {
-        PRInt32 len = contentLength.ToInteger(&rv);
+    if (imageType == imgIContainer::TYPE_RASTER) {
+      /* Use content-length as a size hint for http channels. */
+      if (httpChannel) {
+        nsCAutoString contentLength;
+        rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-length"),
+                                            contentLength);
+        if (NS_SUCCEEDED(rv)) {
+          PRInt32 len = contentLength.ToInteger(&rv);
 
-        // Pass anything usable on so that the imgContainer can preallocate its
-        // source buffer
-        if (len > 0) {
-          PRUint32 sizeHint = (PRUint32) len;
-          sizeHint = PR_MIN(sizeHint, 20000000); /* Bound by something reasonable */
-          mImage->SetSourceSizeHint(sizeHint);
+          // Pass anything usable on so that the RasterImage can preallocate
+          // its source buffer
+          if (len > 0) {
+            PRUint32 sizeHint = (PRUint32) len;
+            sizeHint = PR_MIN(sizeHint, 20000000); /* Bound by something reasonable */
+            RasterImage* rasterImage = static_cast<RasterImage*>(mImage.get());
+            rasterImage->SetSourceSizeHint(sizeHint);
+          }
         }
       }
     }
 
     // If we were waiting on the image to do something, now's our chance.
     if (mDecodeRequested) {
       mImage->RequestDecode();
     }
   }
 
-  // WriteToContainer always consumes everything it gets
+  // WriteToRasterImage always consumes everything it gets
   PRUint32 bytesRead;
-  rv = inStr->ReadSegments(imgContainer::WriteToContainer,
+  rv = inStr->ReadSegments(RasterImage::WriteToRasterImage,
                            static_cast<void*>(mImage),
                            count, &bytesRead);
   if (NS_FAILED(rv)) {
     PR_LOG(gImgLog, PR_LOG_WARNING,
            ("[this=%p] imgRequest::OnDataAvailable -- "
-            "copy to container failed\n", this));
+            "copy to RasterImage failed\n", this));
     this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
     return NS_BINDING_ABORTED;
   }
-  NS_ABORT_IF_FALSE(bytesRead == count, "WriteToContainer should consume everything!");
+  NS_ABORT_IF_FALSE(bytesRead == count, "WriteToRasterImage should consume everything!");
 
   return NS_OK;
 }
 
 static NS_METHOD sniff_mimetype_callback(nsIInputStream* in,
                                          void* closure,
                                          const char* fromRawSegment,
                                          PRUint32 toOffset,
--- a/modules/libpr0n/src/imgRequest.h
+++ b/modules/libpr0n/src/imgRequest.h
@@ -36,17 +36,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef imgRequest_h__
 #define imgRequest_h__
 
-#include "imgContainer.h"
 #include "imgIDecoder.h"
 #include "imgIDecoderObserver.h"
 
 #include "nsIChannelEventSink.h"
 #include "nsIContentSniffer.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIRequest.h"
 #include "nsIProperties.h"
@@ -56,26 +55,31 @@
 
 #include "nsCategoryCache.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsTObserverArray.h"
 #include "nsWeakReference.h"
 #include "ImageErrors.h"
 #include "imgIRequest.h"
-#include "imgContainer.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 
 class imgCacheValidator;
 
 class imgRequestProxy;
 class imgCacheEntry;
 class imgMemoryReporter;
 class imgRequestNotifyRunnable;
 
+namespace mozilla {
+namespace imagelib {
+class Image;
+} // namespace imagelib
+} // namespace mozilla
+
 class imgRequest : public imgIDecoderObserver,
                    public nsIStreamListener,
                    public nsSupportsWeakReference,
                    public nsIChannelEventSink,
                    public nsIInterfaceRequestor,
                    public nsIAsyncVerifyRedirectCallback
 {
 public:
@@ -98,27 +102,24 @@ public:
   // aNotify==PR_FALSE still sends OnStopRequest.
   nsresult RemoveProxy(imgRequestProxy *proxy, nsresult aStatus, PRBool aNotify);
 
   void SniffMimeType(const char *buf, PRUint32 len);
 
   // a request is "reusable" if it has already been loaded, or it is
   // currently being loaded on the same event queue as the new request
   // being made...
-  PRBool IsReusable(void *aCacheId) {
-    return (mImage && mImage->GetStatusTracker().IsLoading()) ||
-           (aCacheId == mCacheId);
-  }
+  PRBool IsReusable(void *aCacheId);
 
   // Cancel, but also ensure that all work done in Init() is undone. Call this
   // only when the channel has failed to open, and so calling Cancel() on it
   // won't be sufficient.
   void CancelAndAbort(nsresult aStatus);
 
-  // Methods that get forwarded to the imgContainer, or deferred until it's
+  // Methods that get forwarded to the Image, or deferred until it's
   // instantiated.
   nsresult LockImage();
   nsresult UnlockImage();
   nsresult RequestDecode();
 
 private:
   friend class imgCacheEntry;
   friend class imgRequestProxy;
@@ -190,17 +191,17 @@ private:
   friend class imgMemoryReporter;
 
   nsCOMPtr<nsIRequest> mRequest;
   // The original URI we were loaded with.
   nsCOMPtr<nsIURI> mURI;
   // The URI we are keyed on in the cache.
   nsCOMPtr<nsIURI> mKeyURI;
   nsCOMPtr<nsIPrincipal> mPrincipal;
-  nsRefPtr<imgContainer> mImage;
+  nsRefPtr<mozilla::imagelib::Image> mImage;
   nsCOMPtr<nsIProperties> mProperties;
   nsCOMPtr<nsISupports> mSecurityInfo;
   nsCOMPtr<nsIChannel> mChannel;
   nsCOMPtr<nsIInterfaceRequestor> mPrevChannelSink;
 
   nsTObserverArray<imgRequestProxy*> mObservers;
 
   nsCString mContentType;
--- a/modules/libpr0n/src/imgRequestProxy.cpp
+++ b/modules/libpr0n/src/imgRequestProxy.cpp
@@ -44,21 +44,24 @@
 #include "nsIServiceManager.h"
 #include "nsIMultiPartChannel.h"
 
 #include "nsString.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 
+#include "Image.h"
 #include "ImageErrors.h"
 #include "ImageLogging.h"
 
 #include "nspr.h"
 
+using namespace mozilla::imagelib;
+
 NS_IMPL_ISUPPORTS4(imgRequestProxy, imgIRequest, nsIRequest,
                    nsISupportsPriority, nsISecurityInfoProvider)
 
 imgRequestProxy::imgRequestProxy() :
   mOwner(nsnull),
   mURI(nsnull),
   mImage(nsnull),
   mPrincipal(nsnull),
@@ -104,17 +107,17 @@ imgRequestProxy::~imgRequestProxy()
          Passing false to aNotify means that we will still get
          OnStopRequest, if needed.
        */
       mOwner->RemoveProxy(this, NS_OK, PR_FALSE);
     }
   }
 }
 
-nsresult imgRequestProxy::Init(imgRequest* request, nsILoadGroup* aLoadGroup, imgContainer* aImage,
+nsresult imgRequestProxy::Init(imgRequest* request, nsILoadGroup* aLoadGroup, Image* aImage,
                                nsIURI* aURI, imgIDecoderObserver* aObserver)
 {
   NS_PRECONDITION(!mOwner && !mListener, "imgRequestProxy is already initialized");
 
   LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", request);
 
   mOwner = request;
   mListener = aObserver;
@@ -505,17 +508,18 @@ NS_IMETHODIMP imgRequestProxy::GetHasTra
     // The safe thing to do is to claim we have data
     *hasData = PR_TRUE;
   }
   return NS_OK;
 }
 
 /** imgIContainerObserver methods **/
 
-void imgRequestProxy::FrameChanged(imgIContainer *container, nsIntRect * dirtyRect)
+void imgRequestProxy::FrameChanged(imgIContainer *container,
+                                   const nsIntRect *dirtyRect)
 {
   LOG_FUNC(gImgLog, "imgRequestProxy::FrameChanged");
 
   if (mListener && !mCanceled) {
     // Hold a ref to the listener while we call it, just in case.
     nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
     mListener->FrameChanged(container, dirtyRect);
   }
@@ -704,17 +708,17 @@ imgRequestProxy::GetStaticRequest(imgIRe
   nsIntRect rect(0, 0, w, h);
   nsCOMPtr<imgIContainer> currentFrame;
   nsresult rv = mImage->ExtractFrame(imgIContainer::FRAME_CURRENT, rect,
                                      imgIContainer::FLAG_SYNC_DECODE,
                                      getter_AddRefs(currentFrame));
   if (NS_FAILED(rv))
     return rv;
 
-  nsRefPtr<imgContainer> frame = static_cast<imgContainer*>(currentFrame.get());
+  nsRefPtr<Image> frame = static_cast<Image*>(currentFrame.get());
 
   // Create a static imgRequestProxy with our new extracted frame.
   nsRefPtr<imgRequestProxy> req = new imgRequestProxy();
   req->Init(nsnull, nsnull, frame, mURI, nsnull);
   req->SetPrincipal(mPrincipal);
 
   NS_ADDREF(*aReturn = req);
 
--- a/modules/libpr0n/src/imgRequestProxy.h
+++ b/modules/libpr0n/src/imgRequestProxy.h
@@ -39,17 +39,16 @@
 
 #ifndef imgRequestProxy_h__
 #define imgRequestProxy_h__
 
 #include "imgIRequest.h"
 #include "imgIDecoderObserver.h"
 #include "nsISecurityInfoProvider.h"
 
-#include "imgIContainer.h"
 #include "imgIDecoder.h"
 #include "nsIRequestObserver.h"
 #include "nsIChannel.h"
 #include "nsILoadGroup.h"
 #include "nsISupportsPriority.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
@@ -62,31 +61,38 @@
      0x1dd2,                                         \
      0x11b2,                                         \
     {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
 }
 
 class imgRequestNotifyRunnable;
 class imgStatusNotifyRunnable;
 
+namespace mozilla {
+namespace imagelib {
+class Image;
+} // namespace imagelib
+} // namespace mozilla
+
 class imgRequestProxy : public imgIRequest, public nsISupportsPriority, public nsISecurityInfoProvider
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIREQUEST
   NS_DECL_NSIREQUEST
   NS_DECL_NSISUPPORTSPRIORITY
   NS_DECL_NSISECURITYINFOPROVIDER
 
   imgRequestProxy();
   virtual ~imgRequestProxy();
 
   // Callers to Init or ChangeOwner are required to call NotifyListener after
   // (although not immediately after) doing so.
-  nsresult Init(imgRequest *request, nsILoadGroup *aLoadGroup, imgContainer* aImage,
+  nsresult Init(imgRequest *request, nsILoadGroup *aLoadGroup,
+                mozilla::imagelib::Image* aImage,
                 nsIURI* aURI, imgIDecoderObserver *aObserver);
 
   nsresult ChangeOwner(imgRequest *aNewOwner); // this will change mOwner.  Do not call this if the previous
                                                // owner has already sent notifications out!
 
   void AddToLoadGroup();
   void RemoveFromLoadGroup(PRBool releaseLoadGroup);
 
@@ -153,17 +159,18 @@ protected:
   void OnStartFrame    (PRUint32 aFrame);
   void OnDataAvailable (PRBool aCurrentFrame, const nsIntRect * aRect);
   void OnStopFrame     (PRUint32 aFrame);
   void OnStopContainer (imgIContainer *aContainer);
   void OnStopDecode    (nsresult status, const PRUnichar *statusArg); 
   void OnDiscard       ();
 
   /* non-virtual imgIContainerObserver methods */
-  void FrameChanged(imgIContainer *aContainer, nsIntRect * aDirtyRect);
+  void FrameChanged(imgIContainer *aContainer,
+                    const nsIntRect *aDirtyRect);
 
   /* non-virtual sort-of-nsIRequestObserver methods */
   void OnStartRequest();
   void OnStopRequest(PRBool aLastPart);
 
   /* Finish up canceling ourselves */
   void DoCancel(nsresult status);
 
@@ -185,17 +192,17 @@ private:
   // means that imgRequest::mObservers will not have any stale pointers in it.
   nsRefPtr<imgRequest> mOwner;
 
   // The URI of our request.
   nsCOMPtr<nsIURI> mURI;
 
   // The image we represent. Is null until data has been received, and is then
   // set by imgRequest.
-  nsRefPtr<imgContainer> mImage;
+  nsRefPtr<mozilla::imagelib::Image> mImage;
 
   // Our principal. Is null until data has been received from the channel, and
   // is then set by imgRequest.
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
   // mListener is only promised to be a weak ref (see imgILoader.idl),
   // but we actually keep a strong ref to it until we've seen our
   // first OnStopRequest.
--- a/modules/libpr0n/src/imgStatusTracker.cpp
+++ b/modules/libpr0n/src/imgStatusTracker.cpp
@@ -37,29 +37,32 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "imgStatusTracker.h"
 
 #include "imgRequest.h"
 #include "imgIContainer.h"
 #include "imgRequestProxy.h"
+#include "Image.h"
 #include "ImageLogging.h"
 
+using namespace mozilla::imagelib;
+
 static nsresult
 GetResultFromImageStatus(PRUint32 aStatus)
 {
   if (aStatus & imgIRequest::STATUS_ERROR)
     return NS_IMAGELIB_ERROR_FAILURE;
   if (aStatus & imgIRequest::STATUS_LOAD_COMPLETE)
     return NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
   return NS_OK;
 }
 
-imgStatusTracker::imgStatusTracker(imgIContainer* aImage)
+imgStatusTracker::imgStatusTracker(Image* aImage)
   : mImage(aImage),
     mState(0),
     mImageStatus(imgIRequest::STATUS_NONE),
     mHadLastPart(PR_FALSE)
 {}
 
 imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther)
   : mImage(aOther.mImage),
@@ -164,17 +167,17 @@ class imgStatusNotifyRunnable : public n
       mStatus.SyncNotify(mProxy);
       return NS_OK;
     }
 
   private:
     imgStatusTracker mStatus;
     // We have to hold on to a reference to the tracker's image, just in case
     // it goes away while we're in the event queue.
-    nsRefPtr<imgIContainer> mImage;
+    nsRefPtr<Image> mImage;
     nsRefPtr<imgRequestProxy> mProxy;
 };
 
 void
 imgStatusTracker::NotifyCurrentState(imgRequestProxy* proxy)
 {
 #ifdef PR_LOGGING
   nsCOMPtr<nsIURI> uri;
@@ -419,25 +422,26 @@ void
 imgStatusTracker::SendDiscard(imgRequestProxy* aProxy)
 {
   if (!aProxy->NotificationsDeferred())
     aProxy->OnDiscard();
 }
 
 /* non-virtual imgIContainerObserver methods */
 void
-imgStatusTracker::RecordFrameChanged(imgIContainer* aContainer, nsIntRect* aDirtyRect)
+imgStatusTracker::RecordFrameChanged(imgIContainer* aContainer,
+                                     const nsIntRect* aDirtyRect)
 {
   // no bookkeeping necessary here - this is only for in-frame updates, which we
   // don't fire while we're recording
 }
 
 void
 imgStatusTracker::SendFrameChanged(imgRequestProxy* aProxy, imgIContainer* aContainer,
-                                   nsIntRect* aDirtyRect)
+                                   const nsIntRect* aDirtyRect)
 {
   if (!aProxy->NotificationsDeferred())
     aProxy->FrameChanged(aContainer, aDirtyRect);
 }
 
 /* non-virtual sort-of-nsIRequestObserver methods */
 void
 imgStatusTracker::RecordStartRequest()
--- a/modules/libpr0n/src/imgStatusTracker.h
+++ b/modules/libpr0n/src/imgStatusTracker.h
@@ -41,16 +41,22 @@
 #define imgStatusTracker_h__
 
 class nsIntRect;
 class imgIContainer;
 class imgRequest;
 class imgRequestProxy;
 class imgStatusNotifyRunnable;
 class imgRequestNotifyRunnable;
+namespace mozilla {
+namespace imagelib {
+class Image;
+} // namespace imagelib
+} // namespace mozilla
+
 
 #include "nsCOMPtr.h"
 #include "nsIRunnable.h"
 #include "prtypes.h"
 #include "nscore.h"
 
 enum {
   stateRequestStarted    = PR_BIT(0),
@@ -58,32 +64,32 @@ enum {
   stateDecodeStarted     = PR_BIT(2),
   stateDecodeStopped     = PR_BIT(3),
   stateFrameStopped      = PR_BIT(4),
   stateRequestStopped    = PR_BIT(5)
 };
 
 /*
  * The image status tracker is a class that encapsulates all the loading and
- * decoding status about an image (imgContainer), and makes it possible to send
- * notifications to imgRequestProxys, both synchronously (i.e., the status now)
- * and asynchronously (the status later).
+ * decoding status about an Image, and makes it possible to send notifications
+ * to imgRequestProxys, both synchronously (i.e., the status now) and
+ * asynchronously (the status later).
  *
  * When a new proxy needs to be notified of the current state of an image, call
  * the Notify() method on this class with the relevant proxy as its argument,
  * and the notifications will be replayed to the proxy asynchronously.
  */
 
 class imgStatusTracker
 {
 public:
   // aImage is the image that this status tracker will pass to the
   // imgRequestProxys in SyncNotify() and EmulateRequestFinished(), and must be
   // alive as long as this instance is, because we hold a weak reference to it.
-  imgStatusTracker(imgIContainer* aImage);
+  imgStatusTracker(mozilla::imagelib::Image* aImage);
   imgStatusTracker(const imgStatusTracker& aOther);
 
   // 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
   // Notify() is called and when we call SyncNotify on |proxy|, and replay them
   // as well.
   void Notify(imgRequest* request, imgRequestProxy* proxy);
@@ -144,32 +150,34 @@ public:
   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 RecordDiscard();
   void SendDiscard(imgRequestProxy* aProxy);
 
   /* non-virtual imgIContainerObserver methods */
-  void RecordFrameChanged(imgIContainer* aContainer, nsIntRect* aDirtyRect);
-  void SendFrameChanged(imgRequestProxy* aProxy, imgIContainer* aContainer, nsIntRect* aDirtyRect);
+  void RecordFrameChanged(imgIContainer* aContainer,
+                          const nsIntRect* aDirtyRect);
+  void SendFrameChanged(imgRequestProxy* aProxy, imgIContainer* aContainer,
+                        const nsIntRect* aDirtyRect);
 
   /* non-virtual sort-of-nsIRequestObserver methods */
   void RecordStartRequest();
   void SendStartRequest(imgRequestProxy* aProxy);
   void RecordStopRequest(PRBool aLastPart, nsresult aStatus);
   void SendStopRequest(imgRequestProxy* aProxy, PRBool aLastPart, nsresult aStatus);
 
 private:
   friend class imgStatusNotifyRunnable;
   friend class imgRequestNotifyRunnable;
 
   nsCOMPtr<nsIRunnable> mRequestRunnable;
 
-  // A weak pointer to the imgIContainer, because the container owns us, and we
+  // A weak pointer to the Image, because it owns us, and we
   // can't create a cycle.
-  imgIContainer* mImage;
+  mozilla::imagelib::Image* mImage;
   PRUint32 mState;
   nsresult mImageStatus;
   PRPackedBool mHadLastPart;
 };
 
 #endif
--- a/modules/libpr0n/src/imgTools.cpp
+++ b/modules/libpr0n/src/imgTools.cpp
@@ -47,17 +47,19 @@
 #include "imgIContainerObserver.h"
 #include "gfxContext.h"
 #include "nsStringStream.h"
 #include "nsComponentManagerUtils.h"
 #include "nsWeakReference.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsStreamUtils.h"
 #include "nsNetUtil.h"
-#include "imgContainer.h"
+#include "RasterImage.h"
+
+using namespace mozilla::imagelib;
 
 /* ========== imgITools implementation ========== */
 
 
 
 NS_IMPL_ISUPPORTS1(imgTools, imgITools)
 
 imgTools::imgTools()
@@ -71,66 +73,71 @@ imgTools::~imgTools()
 }
 
 
 NS_IMETHODIMP imgTools::DecodeImageData(nsIInputStream* aInStr,
                                         const nsACString& aMimeType,
                                         imgIContainer **aContainer)
 {
   nsresult rv;
+  RasterImage* image;  // convenience alias for *aContainer
 
   NS_ENSURE_ARG_POINTER(aInStr);
-  // If the caller didn't provide a container, create one
-  if (!*aContainer) {
-    *aContainer = new imgContainer();
-    if (!*aContainer)
-      return NS_ERROR_OUT_OF_MEMORY;
-    NS_ADDREF(*aContainer);
+
+  // If the caller didn't provide an imgIContainer, create one.
+  if (*aContainer) {
+    NS_ABORT_IF_FALSE((*aContainer)->GetType() == imgIContainer::TYPE_RASTER,
+                      "wrong type of imgIContainer for decoding into");
+    image = static_cast<RasterImage*>(*aContainer);
+  } else {
+    *aContainer = image = new RasterImage();
+    NS_ADDREF(image);
   }
 
-  // Initialize the container. If we're using the one from the caller, we
-  // require that it not be initialized
+  // Initialize the Image. If we're using the one from the caller, we
+  // require that it not be initialized.
   nsCString mimeType(aMimeType);
-  rv = (*aContainer)->Init(nsnull, mimeType.get(), imgIContainer::INIT_FLAG_NONE);
+  rv = image->Init(nsnull, mimeType.get(), Image::INIT_FLAG_NONE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIInputStream> inStream = aInStr;
   if (!NS_InputStreamIsBuffered(aInStr)) {
     nsCOMPtr<nsIInputStream> bufStream;
     rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), aInStr, 1024);
     if (NS_SUCCEEDED(rv))
       inStream = bufStream;
   }
 
   // Figure out how much data we've been passed
   PRUint32 length;
   rv = inStream->Available(&length);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Send the source data to the container. WriteToContainer always
+  // Send the source data to the Image. WriteToRasterImage always
   // consumes everything it gets.
   PRUint32 bytesRead;
-  rv = inStream->ReadSegments(imgContainer::WriteToContainer,
-                              static_cast<void*>(*aContainer),
+  rv = inStream->ReadSegments(RasterImage::WriteToRasterImage,
+                              static_cast<void*>(image),
                               length, &bytesRead);
   NS_ENSURE_SUCCESS(rv, rv);
+  NS_ABORT_IF_FALSE(bytesRead == length, "WriteToRasterImage should consume everything!");
 
 
-  // Let the container know we've sent all the data
-  rv = (*aContainer)->SourceDataComplete();
+  // Let the Image know we've sent all the data
+  rv = image->SourceDataComplete();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // All done
   return NS_OK;
 }
 
 
 NS_IMETHODIMP imgTools::EncodeImage(imgIContainer *aContainer,
-                                          const nsACString& aMimeType,
-                                          nsIInputStream **aStream)
+                                    const nsACString& aMimeType,
+                                    nsIInputStream **aStream)
 {
     return EncodeScaledImage(aContainer, aMimeType, 0, 0, aStream);
 }
 
 
 NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
                                           const nsACString& aMimeType,
                                           PRInt32 aScaledWidth,
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -148,17 +148,17 @@ nsAlertsIconListener::OnStopDecode(imgIR
                                    nsresult status,
                                    const PRUnichar* statusArg)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAlertsIconListener::FrameChanged(imgIContainer* aContainer,
-                                   nsIntRect* aDirtyRect)
+                                   const nsIntRect* aDirtyRect)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAlertsIconListener::OnStopRequest(imgIRequest* aRequest,
                                     PRBool aIsLastPart)
 {
--- a/widget/src/cocoa/nsMenuItemIconX.mm
+++ b/widget/src/cocoa/nsMenuItemIconX.mm
@@ -349,18 +349,18 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconU
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 //
 // imgIContainerObserver
 //
 
 NS_IMETHODIMP
-nsMenuItemIconX::FrameChanged(imgIContainer* aContainer,
-                              nsIntRect*     aDirtyRect)
+nsMenuItemIconX::FrameChanged(imgIContainer*   aContainer,
+                              const nsIntRect* aDirtyRect)
 {
   return NS_OK;
 }
 
 //
 // imgIDecoderObserver
 //
 
--- a/widget/src/windows/nsWindowGfx.cpp
+++ b/widget/src/windows/nsWindowGfx.cpp
@@ -753,22 +753,16 @@ DDRAW_FAILED:
 
 nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer,
                                   PRBool aIsCursor,
                                   PRUint32 aHotspotX,
                                   PRUint32 aHotspotY,
                                   HICON *aIcon) {
 
   nsresult rv;
-  PRUint32 nFrames;
-  rv = aContainer->GetNumFrames(&nFrames);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!nFrames)
-    return NS_ERROR_INVALID_ARG;
 
   // Get the image data
   nsRefPtr<gfxImageSurface> frame;
   aContainer->CopyFrame(imgIContainer::FRAME_CURRENT,
                         imgIContainer::FLAG_SYNC_DECODE,
                         getter_AddRefs(frame));
   if (!frame)
     return NS_ERROR_NOT_AVAILABLE;