Bug 682677 - Eliminated direct access to mInfo->pixel_depth, which is not allowed in libpng15. We access pixel_depth via png_get_IHDR() instead; r=joedrew
authorGlenn Randers-Pehrson <glennrp+bmo@gmail.com>
Sat, 05 Nov 2011 10:48:26 +0000
changeset 81491 aff1bd412058cb6926a8feae1e8c0fc76b4c04a3
parent 81490 8248dbffd64534fb6c65ad3d757b795119e783c6
child 81492 b878590bf618429adedc0a33455667dda524ff46
push id90
push userffxbld
push dateSun, 29 Jan 2012 07:46:52 +0000
treeherdermozilla-release@acddb6b6a01c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoedrew
bugs682677
milestone10.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 682677 - Eliminated direct access to mInfo->pixel_depth, which is not allowed in libpng15. We access pixel_depth via png_get_IHDR() instead; r=joedrew
image/decoders/nsICODecoder.cpp
image/decoders/nsPNGDecoder.h
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -381,18 +381,17 @@ nsICODecoder::WriteInternal(const char* 
       return;
     }
     mPos += aCount;
     aBuffer += aCount;
     aCount = 0;
 
     // Raymond Chen says that 32bpp only are valid PNG ICOs
     // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
-    if (static_cast<nsPNGDecoder*>(mContainedDecoder.get())->HasValidInfo() && 
-        static_cast<nsPNGDecoder*>(mContainedDecoder.get())->GetPixelDepth() != 32) {
+    if (!static_cast<nsPNGDecoder*>(mContainedDecoder.get())->IsValidICO()) {
       PostDataError();
     }
     return;
   }
 
   // We've processed all of the icon dir entries and are within the 
   // bitmap info size
   if (!mIsPNG && mCurrIcon == mNumIcons && mPos >= mImageOffset && 
--- a/image/decoders/nsPNGDecoder.h
+++ b/image/decoders/nsPNGDecoder.h
@@ -68,29 +68,35 @@ public:
 
   void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
                    PRInt32 width, PRInt32 height,
                    gfxASurface::gfxImageFormat format);
   void SetAnimFrameInfo();
 
   void EndImageFrame();
 
-  // Checks if the info header contains valid information
-  bool HasValidInfo() const 
+  // Check if PNG is valid ICO (32bpp RGBA)
+  // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
+  bool IsValidICO() const
   {
-    return mInfo && mInfo->valid;
-  }
+    png_uint_32
+        png_width,  // Unused
+        png_height; // Unused
 
-  // Obtain the pixel depth if available or 0 otherwise
-  PRInt32 GetPixelDepth() const
-  {
-    if (!mInfo) {
-      return 0;
+    int png_bit_depth,
+        png_color_type;
+
+    if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth,
+                     &png_color_type, NULL, NULL, NULL)) {
+
+      return (png_color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+              png_bit_depth == 8);
+    } else {
+      return false;
     }
-    return mInfo->pixel_depth;
   }
 
 public:
   png_structp mPNG;
   png_infop mInfo;
   nsIntRect mFrameRect;
   PRUint8 *mCMSLine;
   PRUint8 *interlacebuf;