diff options
-rw-r--r-- | include/core/SkImageDecoder.h | 10 | ||||
-rw-r--r-- | src/images/SkImageDecoder.cpp | 17 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libico.cpp | 14 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_empty.cpp | 2 |
4 files changed, 43 insertions, 0 deletions
diff --git a/include/core/SkImageDecoder.h b/include/core/SkImageDecoder.h index 67c8257827..191fe53f4c 100644 --- a/include/core/SkImageDecoder.h +++ b/include/core/SkImageDecoder.h @@ -404,7 +404,17 @@ protected: int dstX, int dstY, int width, int height, int srcX, int srcY); + /** + * Copy all fields on this decoder to the other decoder. Used by subclasses + * to decode a subimage using a different decoder, but with the same settings. + */ + void copyFieldsToOther(SkImageDecoder* other); + /** + * Return the default preference being used by the current or latest call to + * decode. + */ + SkBitmap::Config getDefaultPref() { return fDefaultPref; } /** Can be queried from within onDecode, to see if the user (possibly in a different thread) has requested the decode to cancel. If this returns diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp index 0aa752e38f..5d94bb1c2d 100644 --- a/src/images/SkImageDecoder.cpp +++ b/src/images/SkImageDecoder.cpp @@ -50,6 +50,23 @@ SkImageDecoder::~SkImageDecoder() { 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 6335136fa0..b14e19614c 100644 --- a/src/images/SkImageDecoder_libico.cpp +++ b/src/images/SkImageDecoder_libico.cpp @@ -152,6 +152,20 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) 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 94db139656..c225bb1998 100644 --- a/src/ports/SkImageDecoder_empty.cpp +++ b/src/ports/SkImageDecoder_empty.cpp @@ -22,6 +22,8 @@ SkImageDecoder* SkImageDecoder::Factory(SkStream*) { return NULL; } +void SkImageDecoder::copyFieldsToOther(SkImageDecoder* ) {} + bool SkImageDecoder::DecodeFile(const char[], SkBitmap*, SkBitmap::Config, SkImageDecoder::Mode, SkImageDecoder::Format*) { return false; |