Bug 716140 - Track image metadata in a separate object, and sync it to the image once decoding is done. r=jlebar
authorJoe Drew <joe@drew.ca>
Thu, 20 Dec 2012 11:49:25 -0500
changeset 136016 98bab71808e5139de170002a0e9fe8f527d84bd8
parent 136015 0a2205fa1da057c4537897e4e099b9b925a2d02d
child 136017 384efd041a377420a76d480b139bf66030ad92d9
push id2452
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 16:59:38 +0000
treeherdermozilla-beta@d4b152d29d8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs716140
milestone22.0a1
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
Bug 716140 - Track image metadata in a separate object, and sync it to the image once decoding is done. r=jlebar
image/decoders/nsICODecoder.cpp
image/src/Decoder.cpp
image/src/Decoder.h
image/src/ImageMetadata.cpp
image/src/ImageMetadata.h
image/src/Makefile.in
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -6,24 +6,18 @@
 /* This is a Cross-Platform ICO Decoder, which should work everywhere, including
  * Big-Endian machines like the PowerPC. */
 
 #include <stdlib.h>
 
 #include "EndianMacros.h"
 #include "nsICODecoder.h"
 
-#include "nsIInputStream.h"
-#include "nsIComponentManager.h"
 #include "RasterImage.h"
 
-#include "nsIProperties.h"
-#include "nsISupportsPrimitives.h"
-#include <algorithm>
-
 namespace mozilla {
 namespace image {
 
 #define ICONCOUNTOFFSET 4
 #define DIRENTRYOFFSET 6
 #define BITMAPINFOSIZE 40
 #define PREFICONSIZE 16
 
@@ -206,28 +200,17 @@ nsICODecoder::ExtractBIHSizeFromBitmap(i
 }
 
 void
 nsICODecoder::SetHotSpotIfCursor() {
   if (!mIsCursor) {
     return;
   }
 
-  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);
-
-    mImage.Set("hotspotX", intwrapx);
-    mImage.Set("hotspotY", intwrapy);
-  }
+  mImageMetadata.SetHotspot(mDirEntry.mXHotspot, mDirEntry.mYHotspot);
 }
 
 void
 nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
 {
   NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
 
   if (!aCount) // aCount=0 means EOF
--- a/image/src/Decoder.cpp
+++ b/image/src/Decoder.cpp
@@ -276,24 +276,22 @@ Decoder::PostInvalidation(nsIntRect& aRe
 void
 Decoder::PostDecodeDone(int32_t aLoopCount /* = 0 */)
 {
   NS_ABORT_IF_FALSE(!IsSizeDecode(), "Can't be done with decoding with size decode!");
   NS_ABORT_IF_FALSE(!mInFrame, "Can't be done decoding if we're mid-frame!");
   NS_ABORT_IF_FALSE(!mDecodeDone, "Decode already done!");
   mDecodeDone = true;
 
-  // Set premult before DecodingComplete(), since DecodingComplete() calls Optimize()
-  int frames = GetFrameCount();
-  bool isNonPremult = GetDecodeFlags() & DECODER_NO_PREMULTIPLY_ALPHA;
-  for (int i = 0; i < frames; i++) {
-    mImage.SetFrameAsNonPremult(i, isNonPremult);
-  }
+  // Set metadata before DecodingComplete(), since DecodingComplete() calls Optimize()
+  mImageMetadata.SetLoopCount(aLoopCount);
+  mImageMetadata.SetIsNonPremultiplied(GetDecodeFlags() & DECODER_NO_PREMULTIPLY_ALPHA);
 
-  mImage.SetLoopCount(aLoopCount);
+  // Sync metadata to image
+  mImageMetadata.SetOnImage(&mImage);
 
   // Notify
   mImage.DecodingComplete();
   if (mObserver) {
     mObserver->OnStopDecode(NS_OK);
   }
 }
 
--- a/image/src/Decoder.h
+++ b/image/src/Decoder.h
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_IMAGELIB_DECODER_H_
 #define MOZILLA_IMAGELIB_DECODER_H_
 
 #include "RasterImage.h"
 #include "imgDecoderObserver.h"
 #include "mozilla/RefPtr.h"
+#include "ImageMetadata.h"
 
 namespace mozilla {
 namespace image {
 
 class Decoder
 {
 public:
 
@@ -183,16 +184,17 @@ protected:
   void PostDecoderError(nsresult aFailCode);
 
   /*
    * Member variables.
    *
    */
   RasterImage &mImage;
   RefPtr<imgDecoderObserver> mObserver;
+  ImageMetadata mImageMetadata;
 
   uint32_t mDecodeFlags;
   bool mDecodeDone;
   bool mDataError;
 
 private:
   uint32_t mFrameCount; // Number of frames, including anything in-progress
 
new file mode 100644
--- /dev/null
+++ b/image/src/ImageMetadata.cpp
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageMetadata.h"
+
+#include "RasterImage.h"
+#include "nsComponentManagerUtils.h"
+#include "nsSupportsPrimitives.h"
+
+using namespace mozilla::image;
+
+void
+ImageMetadata::SetOnImage(RasterImage* image)
+{
+  if (mHotspotX != -1 && mHotspotY != -1) {
+    nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
+    nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
+    intwrapx->SetData(mHotspotX);
+    intwrapy->SetData(mHotspotY);
+    image->Set("hotspotX", intwrapx);
+    image->Set("hotspotY", intwrapy);
+  }
+
+  image->SetLoopCount(mLoopCount);
+
+  for (uint32_t i = 0; i < image->GetNumFrames(); i++) {
+    image->SetFrameAsNonPremult(i, mIsNonPremultiplied);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/image/src/ImageMetadata.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/StandardInteger.h"
+
+namespace mozilla {
+namespace image {
+
+class RasterImage;
+
+// The metadata about an image that decoders accumulate as they decode.
+class ImageMetadata
+{
+public:
+  ImageMetadata()
+    : mHotspotX(-1)
+    , mHotspotY(-1)
+    , mLoopCount(-1)
+    , mIsNonPremultiplied(false)
+  {}
+
+  // Set the metadata this object represents on an image.
+  void SetOnImage(RasterImage* image);
+
+  void SetHotspot(uint16_t hotspotx, uint16_t hotspoty)
+  {
+    mHotspotX = hotspotx;
+    mHotspotY = hotspoty;
+  }
+  void SetLoopCount(int32_t loopcount)
+  {
+    mLoopCount = loopcount;
+  }
+
+  void SetIsNonPremultiplied(bool nonPremult)
+  {
+    mIsNonPremultiplied = nonPremult;
+  }
+
+private:
+  // The hotspot found on cursors, or -1 if none was found.
+  int32_t mHotspotX;
+  int32_t mHotspotY;
+
+  // The loop count for animated images, or -1 for infinite loop.
+  int32_t mLoopCount;
+
+  bool mIsNonPremultiplied;
+};
+
+} // namespace image
+} // namespace mozilla
--- a/image/src/Makefile.in
+++ b/image/src/Makefile.in
@@ -21,16 +21,17 @@ FAIL_ON_WARNINGS = 1
 EXPORTS		=  imgLoader.h \
 		   imgRequest.h \
 		   imgRequestProxy.h \
 		   $(NULL)
 
 CPPSRCS		= \
 			Image.cpp \
 			ImageFactory.cpp \
+                        ImageMetadata.cpp \
 			ImageWrapper.cpp \
 			Decoder.cpp \
 			DiscardTracker.cpp \
 			FrozenImage.cpp \
 			RasterImage.cpp \
 			ScriptedNotificationObserver.cpp \
 			SVGDocumentWrapper.cpp \
 			VectorImage.cpp \