Allow ico decoder to decode PNG sub-images.

Since Windows Vista, PNG can be embedded in an ICO file. Update
our decoder to support this.

BUG=https://code.google.com/p/skia/issues/detail?id=1398
R=djsollen@google.com

Review URL: https://codereview.chromium.org/18655007

git-svn-id: http://skia.googlecode.com/svn/trunk@9932 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp
index 0aa752e..5d94bb1 100644
--- a/src/images/SkImageDecoder.cpp
+++ b/src/images/SkImageDecoder.cpp
@@ -50,6 +50,23 @@
     SkSafeUnref(fAllocator);
 }
 
+void SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) {
+    if (NULL == other) {
+        return;
+    }
+    other->setPeeker(fPeeker);
+    other->setChooser(fChooser);
+    other->setAllocator(fAllocator);
+    other->setSampleSize(fSampleSize);
+    if (fUsePrefTable) {
+        other->setPrefConfigTable(fPrefTable);
+    } else {
+        other->fDefaultPref = fDefaultPref;
+    }
+    other->setPreferQualityOverSpeed(fPreferQualityOverSpeed);
+    other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors);
+}
+
 SkImageDecoder::Format SkImageDecoder::getFormat() const {
     return kUnknown_Format;
 }
diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp
index 6335136..b14e196 100644
--- a/src/images/SkImageDecoder_libico.cpp
+++ b/src/images/SkImageDecoder_libico.cpp
@@ -152,6 +152,20 @@
     int offset = read4Bytes(buf, 18 + choice*16);
     if ((size_t)(offset + size) > length)
         return false;
+
+    // Check to see if this is a PNG image inside the ICO
+    {
+        SkMemoryStream subStream(buf + offset, size, false);
+        SkAutoTDelete<SkImageDecoder> otherDecoder(SkImageDecoder::Factory(&subStream));
+        if (otherDecoder.get() != NULL) {
+            // Set fields on the other decoder to be the same as this one.
+            this->copyFieldsToOther(otherDecoder.get());
+            if(otherDecoder->decode(&subStream, bm, this->getDefaultPref(), mode)) {
+                return true;
+            }
+        }
+    }
+
     //int infoSize = read4Bytes(buf, offset);             //40
     //int width = read4Bytes(buf, offset+4);              //should == w
     //int height = read4Bytes(buf, offset+8);             //should == 2*h
diff --git a/src/ports/SkImageDecoder_empty.cpp b/src/ports/SkImageDecoder_empty.cpp
index 94db139..c225bb1 100644
--- a/src/ports/SkImageDecoder_empty.cpp
+++ b/src/ports/SkImageDecoder_empty.cpp
@@ -22,6 +22,8 @@
     return NULL;
 }
 
+void SkImageDecoder::copyFieldsToOther(SkImageDecoder* ) {}
+
 bool SkImageDecoder::DecodeFile(const char[], SkBitmap*, SkBitmap::Config,
                                 SkImageDecoder::Mode, SkImageDecoder::Format*) {
     return false;