diff options
-rw-r--r-- | bench/SkipZeroesBench.cpp | 8 | ||||
-rw-r--r-- | include/core/SkImageDecoder.h | 21 | ||||
-rw-r--r-- | samplecode/SampleUnpremul.cpp | 2 | ||||
-rw-r--r-- | src/images/SkDecodingImageGenerator.cpp | 2 | ||||
-rw-r--r-- | src/images/SkImageDecoder.cpp | 15 | ||||
-rw-r--r-- | src/images/SkImageDecoder_astc.cpp | 23 | ||||
-rw-r--r-- | src/images/SkImageDecoder_ktx.cpp | 38 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libbmp.cpp | 16 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libgif.cpp | 19 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libico.cpp | 43 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libjpeg.cpp | 88 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libpng.cpp | 22 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libwebp.cpp | 31 | ||||
-rw-r--r-- | src/images/SkImageDecoder_pkm.cpp | 18 | ||||
-rw-r--r-- | src/images/SkImageDecoder_wbmp.cpp | 16 | ||||
-rw-r--r-- | src/images/SkScaledBitmapSampler.cpp | 4 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_CG.cpp | 16 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_WIC.cpp | 6 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_empty.cpp | 4 | ||||
-rw-r--r-- | tests/ImageDecodingTest.cpp | 6 |
20 files changed, 229 insertions, 169 deletions
diff --git a/bench/SkipZeroesBench.cpp b/bench/SkipZeroesBench.cpp index fc25f8b074..5d18264ea1 100644 --- a/bench/SkipZeroesBench.cpp +++ b/bench/SkipZeroesBench.cpp @@ -83,15 +83,15 @@ protected: // Decode a bunch of times SkBitmap bm; for (int i = 0; i < loops; ++i) { - SkDEBUGCODE(bool success =) fDecoder->decode(&fStream, &bm, - SkImageDecoder::kDecodePixels_Mode); + SkDEBUGCODE(SkImageDecoder::Result result =) fDecoder->decode(&fStream, &bm, + SkImageDecoder::kDecodePixels_Mode); #ifdef SK_DEBUG - if (!success) { + if (SkImageDecoder::kFailure == result) { SkDebugf("failed to decode %s\n", fFilename.c_str()); return; } #endif - SkDEBUGCODE(success =) fStream.rewind(); + SkDEBUGCODE(bool success =) fStream.rewind(); #ifdef SK_DEBUG if (!success) { SkDebugf("failed to rewind %s\n", fFilename.c_str()); diff --git a/include/core/SkImageDecoder.h b/include/core/SkImageDecoder.h index 94831762de..e4ea5e2ec4 100644 --- a/include/core/SkImageDecoder.h +++ b/include/core/SkImageDecoder.h @@ -225,13 +225,26 @@ public: kDecodePixels_Mode //!< return entire bitmap (including pixels) }; + /** Result of a decode. If read as a boolean, a partial success is + considered a success (true). + */ + enum Result { + kFailure = 0, //!< Image failed to decode. bitmap will be + // unchanged. + kPartialSuccess = 1, //!< Part of the image decoded. The rest is + // filled in automatically + kSuccess = 2 //!< The entire image was decoded, if Mode is + // kDecodePixels_Mode, or the bounds were + // decoded, in kDecodeBounds_Mode. + }; + /** Given a stream, decode it into the specified bitmap. If the decoder can decompress the image, it calls bitmap.setInfo(), and then if the Mode is kDecodePixels_Mode, call allocPixelRef(), which will allocated a pixelRef. To access the pixel memory, the codec needs to call lockPixels/unlockPixels on the bitmap. It can then set the pixels with the decompressed image. - * If the image cannot be decompressed, return false. After the + * If the image cannot be decompressed, return kFailure. After the * decoding, the function converts the decoded colortype in bitmap * to pref if possible. Whether a conversion is feasible is * tested by Bitmap::canCopyTo(pref). @@ -244,8 +257,8 @@ public: If a Peeker is installed via setPeeker, it may be used to peek into meta data during the decode. */ - bool decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode); - bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) { + Result decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode); + Result decode(SkStream* stream, SkBitmap* bitmap, Mode mode) { return this->decode(stream, bitmap, kUnknown_SkColorType, mode); } @@ -334,7 +347,7 @@ public: protected: // must be overridden in subclasses. This guy is called by decode(...) - virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0; + virtual Result onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0; // If the decoder wants to support tiled based decoding, // this method must be overridden. This guy is called by buildTileIndex(...) diff --git a/samplecode/SampleUnpremul.cpp b/samplecode/SampleUnpremul.cpp index 992444d05d..ffe4428b48 100644 --- a/samplecode/SampleUnpremul.cpp +++ b/samplecode/SampleUnpremul.cpp @@ -182,7 +182,7 @@ private: decoder->setRequireUnpremultipliedColors(true); } fDecodeSucceeded = decoder->decode(&stream, &fBitmap, kN32_SkColorType, - SkImageDecoder::kDecodePixels_Mode); + SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure; this->inval(NULL); } diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp index a90c1cf01f..cdee7c1676 100644 --- a/src/images/SkDecodingImageGenerator.cpp +++ b/src/images/SkDecodingImageGenerator.cpp @@ -171,7 +171,7 @@ bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info, TargetAllocator allocator(fInfo, pixels, rowBytes); decoder->setAllocator(&allocator); bool success = decoder->decode(fStream, &bitmap, info.colorType(), - SkImageDecoder::kDecodePixels_Mode); + SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure; decoder->setAllocator(NULL); if (!success) { return false; diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp index f9b04e39a7..c5e973903d 100644 --- a/src/images/SkImageDecoder.cpp +++ b/src/images/SkImageDecoder.cpp @@ -156,7 +156,8 @@ SkColorType SkImageDecoder::getPrefColorType(SrcDepth srcDepth, bool srcHasAlpha return ct; } -bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref, Mode mode) { +SkImageDecoder::Result SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref, + Mode mode) { // we reset this to false before calling onDecode fShouldCancelDecode = false; // assign this, for use by getPrefColorType(), in case fUsePrefTable is false @@ -164,12 +165,12 @@ bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref, Mo // pass a temporary bitmap, so that if we return false, we are assured of // leaving the caller's bitmap untouched. - SkBitmap tmp; - if (!this->onDecode(stream, &tmp, mode)) { - return false; + SkBitmap tmp; + const Result result = this->onDecode(stream, &tmp, mode); + if (kFailure != result) { + bm->swap(tmp); } - bm->swap(tmp); - return true; + return result; } bool SkImageDecoder::decodeSubset(SkBitmap* bm, const SkIRect& rect, SkColorType pref) { @@ -272,7 +273,7 @@ bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, SkCo SkImageDecoder* codec = SkImageDecoder::Factory(stream); if (codec) { - success = codec->decode(stream, bm, pref, mode); + success = codec->decode(stream, bm, pref, mode) != kFailure; if (success && format) { *format = codec->getFormat(); if (kUnknown_Format == *format) { diff --git a/src/images/SkImageDecoder_astc.cpp b/src/images/SkImageDecoder_astc.cpp index 79e98047d6..30f42f05df 100644 --- a/src/images/SkImageDecoder_astc.cpp +++ b/src/images/SkImageDecoder_astc.cpp @@ -24,7 +24,7 @@ public: } protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: typedef SkImageDecoder INHERITED; @@ -42,11 +42,11 @@ static inline int read_24bit(const uint8_t* buf) { (static_cast<int>(buf[2]) << 16); } -bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { SkAutoMalloc autoMal; const size_t length = SkCopyStreamToStorage(&autoMal, stream); if (0 == length) { - return false; + return kFailure; } unsigned char* buf = (unsigned char*)autoMal.get(); @@ -63,7 +63,7 @@ bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { if (1 != blockDimZ) { // We don't support decoding 3D - return false; + return kFailure; } // Choose the proper ASTC format @@ -98,7 +98,7 @@ bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { astcFormat = SkTextureCompressor::kASTC_12x12_Format; } else { // We don't support any other block dimensions.. - return false; + return kFailure; } // Advance buf past the block dimensions @@ -111,7 +111,7 @@ bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { if (1 != depth) { // We don't support decoding 3D. - return false; + return kFailure; } // Advance the buffer past the image dimensions @@ -120,7 +120,7 @@ bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER // should we allow the Chooser (if present) to pick a config for us??? if (!this->chooseFromOneChoice(kN32_SkColorType, width, height)) { - return false; + return kFailure; } #endif @@ -139,18 +139,18 @@ bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(), alphaType)); if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } if (!this->allocPixelRef(bm, NULL)) { - return false; + return kFailure; } // Lock the pixels, since we're about to write to them... SkAutoLockPixels alp(*bm); if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, *this)) { - return false; + return kFailure; } // ASTC Data is encoded as RGBA pixels, so we should extract it as such @@ -161,6 +161,7 @@ bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // Decode ASTC if (!SkTextureCompressor::DecompressBufferFromFormat( outRGBADataPtr, width*4, buf, width, height, astcFormat)) { + return kFailure; } // Set each of the pixels... @@ -173,7 +174,7 @@ bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { srcRow += sampler.srcDY() * srcRowBytes; } - return true; + return kSuccess; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/images/SkImageDecoder_ktx.cpp b/src/images/SkImageDecoder_ktx.cpp index 20c8bbc00b..8566375f0c 100644 --- a/src/images/SkImageDecoder_ktx.cpp +++ b/src/images/SkImageDecoder_ktx.cpp @@ -41,22 +41,22 @@ public: } protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: typedef SkImageDecoder INHERITED; }; -bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // TODO: Implement SkStream::copyToData() that's cheap for memory and file streams SkAutoDataUnref data(SkCopyStreamToData(stream)); if (NULL == data) { - return false; + return kFailure; } SkKTXFile ktxFile(data); if (!ktxFile.valid()) { - return false; + return kFailure; } const unsigned short width = ktxFile.width(); @@ -65,7 +65,7 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER // should we allow the Chooser (if present) to pick a config for us??? if (!this->chooseFromOneChoice(kN32_SkColorType, width, height)) { - return false; + return kFailure; } #endif @@ -84,7 +84,7 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // If the client wants unpremul colors and we only have // premul, then we cannot honor their wish. if (bSrcIsPremul) { - return false; + return kFailure; } } else { alphaType = kPremul_SkAlphaType; @@ -121,12 +121,12 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { } if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } // If we've made it this far, then we know how to grok the data. if (!this->allocPixelRef(bm, NULL)) { - return false; + return kFailure; } // Lock the pixels, since we're about to write to them... @@ -134,7 +134,7 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { if (isCompressedAlpha) { if (!sampler.begin(bm, SkScaledBitmapSampler::kGray, *this)) { - return false; + return kFailure; } // Alpha data is only a single byte per pixel. @@ -146,7 +146,7 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData()); if (!SkTextureCompressor::DecompressBufferFromFormat( outRGBDataPtr, width, buf, width, height, ktxCompressedFormat)) { - return false; + return kFailure; } // Set each of the pixels... @@ -159,11 +159,11 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { srcRow += sampler.srcDY() * srcRowBytes; } - return true; + return kSuccess; } else if (ktxFile.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { - return false; + return kFailure; } // ETC1 Data is encoded as RGB pixels, so we should extract it as such @@ -175,7 +175,7 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData()); if (!SkTextureCompressor::DecompressBufferFromFormat( outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor::kETC1_Format)) { - return false; + return kFailure; } // Set each of the pixels... @@ -188,13 +188,13 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { srcRow += sampler.srcDY() * srcRowBytes; } - return true; + return kSuccess; } else if (ktxFile.isRGB8()) { // Uncompressed RGB data (without alpha) if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { - return false; + return kFailure; } // Just need to read RGB pixels @@ -207,7 +207,7 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { srcRow += sampler.srcDY() * srcRowBytes; } - return true; + return kSuccess; } else if (ktxFile.isRGBA8()) { @@ -224,7 +224,7 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { } if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, opts)) { - return false; + return kFailure; } // Just need to read RGBA pixels @@ -237,10 +237,10 @@ bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { srcRow += sampler.srcDY() * srcRowBytes; } - return true; + return kSuccess; } - return false; + return kFailure; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp index 7b87e40039..af868e30a7 100644 --- a/src/images/SkImageDecoder_libbmp.cpp +++ b/src/images/SkImageDecoder_libbmp.cpp @@ -24,7 +24,7 @@ public: } protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE; private: typedef SkImageDecoder INHERITED; @@ -92,7 +92,7 @@ private: bool fJustBounds; }; -bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // First read the entire stream, so that all of the data can be passed to // the BmpDecoderHelper. @@ -101,7 +101,7 @@ bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // Byte length of all of the data. const size_t length = SkCopyStreamToStorage(&storage, stream); if (0 == length) { - return 0; + return kFailure; } const bool justBounds = SkImageDecoder::kDecodeBounds_Mode == mode; @@ -113,7 +113,7 @@ bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { const int max_pixels = 16383*16383; // max width*height if (!helper.DecodeImage((const char*)storage.get(), length, max_pixels, &callback)) { - return false; + return kFailure; } } @@ -136,17 +136,17 @@ bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { colorType, kOpaque_SkAlphaType)); if (justBounds) { - return true; + return kSuccess; } if (!this->allocPixelRef(bm, NULL)) { - return false; + return kFailure; } SkAutoLockPixels alp(*bm); if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { - return false; + return kFailure; } const int srcRowBytes = width * 3; @@ -158,5 +158,5 @@ bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { sampler.next(srcRow); srcRow += sampler.srcDY() * srcRowBytes; } - return true; + return kSuccess; } diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp index 81071c9515..fb5d18fc08 100644 --- a/src/images/SkImageDecoder_libgif.cpp +++ b/src/images/SkImageDecoder_libgif.cpp @@ -24,7 +24,7 @@ public: } protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE; private: typedef SkImageDecoder INHERITED; @@ -152,14 +152,15 @@ static int find_transpIndex(const SavedImage& image, int colorCount) { return transpIndex; } -static bool error_return(const SkBitmap& bm, const char msg[]) { +static SkImageDecoder::Result error_return(const SkBitmap& bm, const char msg[]) { if (!c_suppressGIFImageDecoderWarnings) { SkDebugf("libgif error [%s] bitmap [%d %d] pixels %p colortable %p\n", msg, bm.width(), bm.height(), bm.getPixels(), bm.getColorTable()); } - return false; + return SkImageDecoder::kFailure; } + static void gif_warning(const SkBitmap& bm, const char msg[]) { if (!c_suppressGIFImageDecoderWarnings) { SkDebugf("libgif warning [%s] bitmap [%d %d] pixels %p colortable %p\n", @@ -228,7 +229,7 @@ static void sanitize_indexed_bitmap(SkBitmap* bm) { } } -bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { #if GIFLIB_MAJOR < 5 GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc); #else @@ -322,7 +323,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { kIndex_8_SkColorType, kPremul_SkAlphaType)); if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } @@ -423,7 +424,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { sampler.sampleInterlaced(scanline, iter.currY()); iter.next(); } - return true; + return kPartialSuccess; } sampler.sampleInterlaced(scanline, iter.currY()); iter.next(); @@ -439,7 +440,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { for (; y < outHeight; y++) { sampler.next(scanline); } - return true; + return kPartialSuccess; } // scanline now contains the raw data. Sample it. sampler.next(scanline); @@ -453,7 +454,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { skip_src_rows(gif, scanline, innerWidth, innerHeight - read); } sanitize_indexed_bitmap(bm); - return true; + return kSuccess; } break; case EXTENSION_RECORD_TYPE: @@ -498,7 +499,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { } while (recType != TERMINATE_RECORD_TYPE); sanitize_indexed_bitmap(bm); - return true; + return kSuccess; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp index 7855546a2c..4d19714a11 100644 --- a/src/images/SkImageDecoder_libico.cpp +++ b/src/images/SkImageDecoder_libico.cpp @@ -20,7 +20,7 @@ public: } protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: typedef SkImageDecoder INHERITED; @@ -72,12 +72,12 @@ static int calculateRowBytesFor8888(int w, int bitCount) return 0; } -bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) +SkImageDecoder::Result SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { SkAutoMalloc autoMal; const size_t length = SkCopyStreamToStorage(&autoMal, stream); if (0 == length) { - return false; + return kFailure; } unsigned char* buf = (unsigned char*)autoMal.get(); @@ -86,13 +86,16 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) //incorrect values, but still decode properly? int reserved = read2Bytes(buf, 0); // 0 int type = read2Bytes(buf, 2); // 1 - if (reserved != 0 || type != 1) - return false; + if (reserved != 0 || type != 1) { + return kFailure; + } + int count = read2Bytes(buf, 4); //need to at least have enough space to hold the initial table of info - if (length < (size_t)(6 + count*16)) - return false; + if (length < (size_t)(6 + count*16)) { + return kFailure; + } #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER int choice; @@ -137,8 +140,9 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) } //you never know what the chooser is going to supply - if (choice >= count || choice < 0) - return false; + if (choice >= count || choice < 0) { + return kFailure; + } #else const int choice = 0; // TODO: fold this value into the expressions below #endif @@ -156,7 +160,7 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) const size_t offset = read4Bytes(buf, 18 + choice*16); // promote the sum to 64-bits to avoid overflow if (((uint64_t)offset + size) > length) { - return false; + return kFailure; } // Check to see if this is a PNG image inside the ICO @@ -165,13 +169,18 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SkAutoTDelete<SkImageDecoder> otherDecoder(SkImageDecoder::Factory(&subStream)); if (otherDecoder.get() != NULL) { // Disallow nesting ICO files within one another + // FIXME: Can ICO files contain other formats besides PNG? if (otherDecoder->getFormat() == SkImageDecoder::kICO_Format) { - return false; + return kFailure; } // 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; + const Result result = otherDecoder->decode(&subStream, bm, this->getDefaultPref(), + mode); + // FIXME: Should we just return result here? Is it possible that data that looked like + // a subimage was not, but was actually a valid ICO? + if (result != kFailure) { + return result; } } } @@ -209,7 +218,7 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) break; default: SkDEBUGF(("Decoding %ibpp is unimplemented\n", bitCount)); - return false; + return kFailure; } //these should all be zero, but perhaps are not - need to check @@ -260,13 +269,13 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) if (SkImageDecoder::kDecodeBounds_Mode == mode) { delete[] colors; - return true; + return kSuccess; } if (!this->allocPixelRef(bm, NULL)) { delete[] colors; - return false; + return kFailure; } SkAutoLockPixels alp(*bm); @@ -296,7 +305,7 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) //ensure we haven't read off the end? //of course this doesn't help us if the andOffset was a lie... //return andOffset + (andLineWidth >> 3) <= length; - return true; + return kSuccess; } //onDecode //function to place the pixel, determined by the bitCount diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp index 4103eefede..082adca04a 100644 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ b/src/images/SkImageDecoder_libjpeg.cpp @@ -238,7 +238,7 @@ protected: virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) SK_OVERRIDE; virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRIDE; #endif - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; virtual bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3], size_t rowBytes[3], SkYUVColorSpace* colorSpace) SK_OVERRIDE; @@ -325,9 +325,11 @@ static bool skip_src_rows_tile(jpeg_decompress_struct* cinfo, } #endif +/////////////////////////////////////////////////////////////////////////////// + // This guy exists just to aid in debugging, as it allows debuggers to just // set a break-point in one place to see all error exists. -static bool return_false(const jpeg_decompress_struct& cinfo, +static void print_jpeg_decoder_errors(const jpeg_decompress_struct& cinfo, int width, int height, const char caller[]) { if (!(c_suppressJPEGImageDecoderErrors)) { char buffer[JMSG_LENGTH_MAX]; @@ -335,14 +337,28 @@ static bool return_false(const jpeg_decompress_struct& cinfo, SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n", cinfo.err->msg_code, buffer, caller, width, height); } - return false; // must always return false +} + +static bool return_false(const jpeg_decompress_struct& cinfo, + const char caller[]) { + print_jpeg_decoder_errors(cinfo, 0, 0, caller); + return false; } static bool return_false(const jpeg_decompress_struct& cinfo, const SkBitmap& bm, const char caller[]) { - return return_false(cinfo, bm.width(), bm.height(), caller); + print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller); + return false; +} + +static SkImageDecoder::Result return_failure(const jpeg_decompress_struct& cinfo, + const SkBitmap& bm, const char caller[]) { + print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller); + return SkImageDecoder::kFailure; } +/////////////////////////////////////////////////////////////////////////////// + // Convert a scanline of CMYK samples to RGBX in place. Note that this // method moves the "scanline" pointer in its processing static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) { @@ -491,7 +507,6 @@ static void adjust_out_color_space_and_dither(jpeg_decompress_struct* cinfo, #endif } - /** Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. Used when decoding fails partway through reading scanlines to fill @@ -537,7 +552,7 @@ static bool get_src_config(const jpeg_decompress_struct& cinfo, return true; } -bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #ifdef TIME_DECODE SkAutoTime atm("JPEG Decode"); #endif @@ -553,7 +568,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // All objects need to be instantiated before this setjmp call so that // they will be cleaned up properly if an error occurs. if (setjmp(errorManager.fJmpBuf)) { - return return_false(cinfo, *bm, "setjmp"); + return return_failure(cinfo, *bm, "setjmp"); } initialize_info(&cinfo, &srcManager); @@ -561,7 +576,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { int status = jpeg_read_header(&cinfo, true); if (status != JPEG_HEADER_OK) { - return return_false(cinfo, *bm, "read_header"); + return return_failure(cinfo, *bm, "read_header"); } /* Try to fulfill the requested sampleSize. Since jpeg can do it (when it @@ -588,8 +603,9 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // individual pixel. It is very unlikely to be opaque, since // an opaque A8 bitmap would not be very interesting. // Otherwise, a jpeg image is opaque. - return bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.image_height, - colorType, alphaType)); + bool success = bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.image_height, + colorType, alphaType)); + return success ? kSuccess : kFailure; } /* image_width and image_height are the original dimensions, available @@ -613,10 +629,11 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // individual pixel. It is very unlikely to be opaque, since // an opaque A8 bitmap would not be very interesting. // Otherwise, a jpeg image is opaque. - return bm->setInfo(SkImageInfo::Make(smpl.scaledWidth(), smpl.scaledHeight(), - colorType, alphaType)); + bool success = bm->setInfo(SkImageInfo::Make(smpl.scaledWidth(), smpl.scaledHeight(), + colorType, alphaType)); + return success ? kSuccess : kFailure; } else { - return return_false(cinfo, *bm, "start_decompress"); + return return_failure(cinfo, *bm, "start_decompress"); } } sampleSize = recompute_sampleSize(sampleSize, cinfo); @@ -624,7 +641,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER // should we allow the Chooser (if present) to pick a colortype for us??? if (!this->chooseFromOneChoice(colorType, cinfo.output_width, cinfo.output_height)) { - return return_false(cinfo, *bm, "chooseFromOneChoice"); + return return_failure(cinfo, *bm, "chooseFromOneChoice"); } #endif @@ -636,10 +653,10 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(), colorType, alphaType)); if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } if (!this->allocPixelRef(bm, NULL)) { - return return_false(cinfo, *bm, "allocPixelRef"); + return return_failure(cinfo, *bm, "allocPixelRef"); } SkAutoLockPixels alp(*bm); @@ -662,15 +679,16 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // so return early. We will return a partial image. fill_below_level(cinfo.output_scanline, bm); cinfo.output_scanline = cinfo.output_height; - break; // Skip to jpeg_finish_decompress() + jpeg_finish_decompress(&cinfo); + return kPartialSuccess; } if (this->shouldCancelDecode()) { - return return_false(cinfo, *bm, "shouldCancelDecode"); + return return_failure(cinfo, *bm, "shouldCancelDecode"); } rowptr += bpr; } jpeg_finish_decompress(&cinfo); - return true; + return kSuccess; } #endif @@ -679,11 +697,11 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { int srcBytesPerPixel; if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) { - return return_false(cinfo, *bm, "jpeg colorspace"); + return return_failure(cinfo, *bm, "jpeg colorspace"); } if (!sampler.begin(bm, sc, *this)) { - return return_false(cinfo, *bm, "sampler.begin"); + return return_failure(cinfo, *bm, "sampler.begin"); } SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel); @@ -691,7 +709,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // Possibly skip initial rows [sampler.srcY0] if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { - return return_false(cinfo, *bm, "skip rows"); + return return_failure(cinfo, *bm, "skip rows"); } // now loop through scanlines until y == bm->height() - 1 @@ -703,10 +721,11 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // so return early. We will return a partial image. fill_below_level(y, bm); cinfo.output_scanline = cinfo.output_height; - break; // Skip to jpeg_finish_decompress() + jpeg_finish_decompress(&cinfo); + return kSuccess; } if (this->shouldCancelDecode()) { - return return_false(cinfo, *bm, "shouldCancelDecode"); + return return_failure(cinfo, *bm, "shouldCancelDecode"); } if (JCS_CMYK == cinfo.out_color_space) { @@ -720,20 +739,22 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { } if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) { - return return_false(cinfo, *bm, "skip rows"); + return return_failure(cinfo, *bm, "skip rows"); } } // we formally skip the rest, so we don't get a complaint from libjpeg if (!skip_src_rows(&cinfo, srcRow, cinfo.output_height - cinfo.output_scanline)) { - return return_false(cinfo, *bm, "skip rows"); + return return_failure(cinfo, *bm, "skip rows"); } jpeg_finish_decompress(&cinfo); - return true; + return kSuccess; } +/////////////////////////////////////////////////////////////////////////////// + enum SizeType { kSizeForMemoryAllocation_SizeType, kActualSize_SizeType @@ -818,8 +839,9 @@ static bool output_raw_data(jpeg_decompress_struct& cinfo, void* planes[3], size } JDIMENSION scanlinesRead = jpeg_read_raw_data(&cinfo, bufferraw, yScanlinesToRead); - if (scanlinesRead == 0) + if (scanlinesRead == 0) { return false; + } if (hasYLastRow) { memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth); @@ -857,7 +879,7 @@ bool SkJPEGImageDecoder::onDecodeYUV8Planes(SkStream* stream, SkISize componentS // All objects need to be instantiated before this setjmp call so that // they will be cleaned up properly if an error occurs. if (setjmp(errorManager.fJmpBuf)) { - return return_false(cinfo, 0, 0, "setjmp YUV8"); + return return_false(cinfo, "setjmp YUV8"); } initialize_info(&cinfo, &srcManager); @@ -865,7 +887,7 @@ bool SkJPEGImageDecoder::onDecodeYUV8Planes(SkStream* stream, SkISize componentS int status = jpeg_read_header(&cinfo, true); if (status != JPEG_HEADER_OK) { - return return_false(cinfo, 0, 0, "read_header YUV8"); + return return_false(cinfo, "read_header YUV8"); } if (cinfo.jpeg_color_space != JCS_YCbCr) { @@ -897,11 +919,11 @@ bool SkJPEGImageDecoder::onDecodeYUV8Planes(SkStream* stream, SkISize componentS jpeg_start_decompress(), and then read output_width and output_height. */ if (!jpeg_start_decompress(&cinfo)) { - return return_false(cinfo, 0, 0, "start_decompress YUV8"); + return return_false(cinfo, "start_decompress YUV8"); } if (!output_raw_data(cinfo, planes, rowBytes)) { - return return_false(cinfo, 0, 0, "output_raw_data"); + return return_false(cinfo, "output_raw_data"); } update_components_sizes(cinfo, componentSizes, kActualSize_SizeType); @@ -914,6 +936,8 @@ bool SkJPEGImageDecoder::onDecodeYUV8Planes(SkStream* stream, SkISize componentS return true; } +/////////////////////////////////////////////////////////////////////////////// + #ifdef SK_BUILD_FOR_ANDROID bool SkJPEGImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int *width, int *height) { diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp index 9fe5fb9c95..0890eaacaf 100644 --- a/src/images/SkImageDecoder_libpng.cpp +++ b/src/images/SkImageDecoder_libpng.cpp @@ -91,7 +91,7 @@ protected: virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) SK_OVERRIDE; virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) SK_OVERRIDE; #endif - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: SkPNGImageIndex* fImageIndex; @@ -302,19 +302,19 @@ bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp, return true; } -bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, - Mode mode) { +SkImageDecoder::Result SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, + Mode mode) { png_structp png_ptr; png_infop info_ptr; if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { - return false; + return kFailure; } PNGAutoClean autoClean(png_ptr, info_ptr); if (setjmp(png_jmpbuf(png_ptr))) { - return false; + return kFailure; } png_uint_32 origWidth, origHeight; @@ -327,7 +327,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, SkPMColor theTranspColor = 0; // 0 tells us not to try to match if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &theTranspColor)) { - return false; + return kFailure; } SkAlphaType alphaType = this->getRequireUnpremultipliedColors() ? @@ -338,7 +338,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, colorType, alphaType)); if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } // from here down we are concerned with colortables and pixels @@ -357,7 +357,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, if (!this->allocPixelRef(decodedBitmap, kIndex_8_SkColorType == colorType ? colorTable : NULL)) { - return false; + return kFailure; } SkAutoLockPixels alp(*decodedBitmap); @@ -415,7 +415,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, */ SkAutoLockColors ctLock(colorTable); if (!sampler.begin(decodedBitmap, sc, *this, ctLock.colors())) { - return false; + return kFailure; } const int height = decodedBitmap->height(); @@ -472,7 +472,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, // Fall through. case kARGB_4444_SkColorType: // We have chosen not to support unpremul for these colortypes. - return false; + return kFailure; default: { // Fall through to finish the decode. This colortype either // supports unpremul or it is irrelevant because it has no @@ -485,7 +485,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, if (!reallyHasAlpha) { decodedBitmap->setAlphaType(kOpaque_SkAlphaType); } - return true; + return kSuccess; } diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp index f32587ddcc..8bf15c92e6 100644 --- a/src/images/SkImageDecoder_libwebp.cpp +++ b/src/images/SkImageDecoder_libwebp.cpp @@ -111,7 +111,7 @@ public: protected: virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) SK_OVERRIDE; virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRIDE; - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: /** @@ -162,11 +162,22 @@ private: // This guy exists just to aid in debugging, as it allows debuggers to just // set a break-point in one place to see all error exists. -static bool return_false(const SkBitmap& bm, const char msg[]) { +static void print_webp_error(const SkBitmap& bm, const char msg[]) { SkDEBUGF(("libwebp error %s [%d %d]", msg, bm.width(), bm.height())); +} + +static bool return_false(const SkBitmap& bm, const char msg[]) { + print_webp_error(bm, msg); return false; // must always return false } +static SkImageDecoder::Result return_failure(const SkBitmap& bm, const char msg[]) { + print_webp_error(bm, msg); + return SkImageDecoder::kFailure; // must always return kFailure +} + +/////////////////////////////////////////////////////////////////////////////// + static WEBP_CSP_MODE webp_decode_mode(const SkBitmap* decodedBitmap, bool premultiply) { WEBP_CSP_MODE mode = MODE_LAST; const SkColorType ct = decodedBitmap->colorType(); @@ -409,15 +420,15 @@ bool SkWEBPImageDecoder::onDecodeSubset(SkBitmap* decodedBitmap, return true; } -bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, - Mode mode) { +SkImageDecoder::Result SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, + Mode mode) { #ifdef TIME_DECODE AutoTimeMillis atm("WEBP Decode"); #endif int origWidth, origHeight, hasAlpha; if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { - return false; + return kFailure; } this->fHasAlpha = hasAlpha; @@ -425,16 +436,16 @@ bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(), sampler.scaledHeight())) { - return false; + return kFailure; } // If only bounds are requested, done if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } if (!this->allocPixelRef(decodedBitmap, NULL)) { - return return_false(*decodedBitmap, "allocPixelRef"); + return return_failure(*decodedBitmap, "allocPixelRef"); } SkAutoLockPixels alp(*decodedBitmap); @@ -442,11 +453,11 @@ bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, WebPDecoderConfig config; if (!webp_get_config_resize(&config, decodedBitmap, origWidth, origHeight, this->shouldPremultiply())) { - return false; + return kFailure; } // Decode the WebP image data stream using WebP incremental decoding. - return webp_idecode(stream, &config); + return webp_idecode(stream, &config) ? kSuccess : kFailure; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/images/SkImageDecoder_pkm.cpp b/src/images/SkImageDecoder_pkm.cpp index f5fd4b3fbc..746ae40c4c 100644 --- a/src/images/SkImageDecoder_pkm.cpp +++ b/src/images/SkImageDecoder_pkm.cpp @@ -24,7 +24,7 @@ public: } protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: typedef SkImageDecoder INHERITED; @@ -32,11 +32,11 @@ private: ///////////////////////////////////////////////////////////////////////////////////////// -bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { SkAutoMalloc autoMal; const size_t length = SkCopyStreamToStorage(&autoMal, stream); if (0 == length) { - return false; + return kFailure; } unsigned char* buf = (unsigned char*)autoMal.get(); @@ -50,7 +50,7 @@ bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER // should we allow the Chooser (if present) to pick a config for us??? if (!this->chooseFromOneChoice(kN32_SkColorType, width, height)) { - return false; + return kFailure; } #endif @@ -61,18 +61,18 @@ bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(), kOpaque_SkAlphaType)); if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } if (!this->allocPixelRef(bm, NULL)) { - return false; + return kFailure; } // Lock the pixels, since we're about to write to them... SkAutoLockPixels alp(*bm); if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { - return false; + return kFailure; } // Advance buffer past the header @@ -86,7 +86,7 @@ bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // Decode ETC1 if (!SkTextureCompressor::DecompressBufferFromFormat( outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor::kETC1_Format)) { - return false; + return kFailure; } // Set each of the pixels... @@ -99,7 +99,7 @@ bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { srcRow += sampler.srcDY() * srcRowBytes; } - return true; + return kSuccess; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/images/SkImageDecoder_wbmp.cpp b/src/images/SkImageDecoder_wbmp.cpp index 0bf138940d..7a6f76ed34 100644 --- a/src/images/SkImageDecoder_wbmp.cpp +++ b/src/images/SkImageDecoder_wbmp.cpp @@ -22,7 +22,7 @@ public: } protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: typedef SkImageDecoder INHERITED; @@ -99,13 +99,13 @@ static void expand_bits_to_bytes(uint8_t dst[], const uint8_t src[], int bits) } } -bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, - Mode mode) +SkImageDecoder::Result SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, + Mode mode) { wbmp_head head; if (!head.init(stream)) { - return false; + return kFailure; } int width = head.fWidth; @@ -115,7 +115,7 @@ bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, kIndex_8_SkColorType, kOpaque_SkAlphaType)); if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE }; @@ -123,7 +123,7 @@ bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, SkAutoUnref aur(ct); if (!this->allocPixelRef(decodedBitmap, ct)) { - return false; + return kFailure; } SkAutoLockPixels alp(*decodedBitmap); @@ -135,7 +135,7 @@ bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, size_t srcSize = height * srcRB; uint8_t* src = dst + decodedBitmap->getSize() - srcSize; if (stream->read(src, srcSize) != srcSize) { - return false; + return kFailure; } for (int y = 0; y < height; y++) @@ -145,7 +145,7 @@ bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, src += srcRB; } - return true; + return kSuccess; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp index d78502d2bb..fe425d58b1 100644 --- a/src/images/SkScaledBitmapSampler.cpp +++ b/src/images/SkScaledBitmapSampler.cpp @@ -835,8 +835,8 @@ class DummyDecoder : public SkImageDecoder { public: DummyDecoder() {} protected: - virtual bool onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode) SK_OVERRIDE { - return false; + virtual Result onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode) SK_OVERRIDE { + return kFailure; } }; diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp index 3e3075cc13..0358aec18c 100644 --- a/src/ports/SkImageDecoder_CG.cpp +++ b/src/ports/SkImageDecoder_CG.cpp @@ -48,7 +48,7 @@ static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) { class SkImageDecoder_CG : public SkImageDecoder { protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode); + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode); }; static void argb_4444_force_opaque(void* row, int count) { @@ -103,17 +103,17 @@ static void force_opaque(SkBitmap* bm) { #define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast) -bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); if (NULL == imageSrc) { - return false; + return kFailure; } SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, NULL); if (NULL == image) { - return false; + return kFailure; } SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image); @@ -122,17 +122,17 @@ bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { bm->setInfo(SkImageInfo::MakeN32Premul(width, height)); if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; + return kSuccess; } if (!this->allocPixelRef(bm, NULL)) { - return false; + return kFailure; } SkAutoLockPixels alp(*bm); if (!SkCopyPixelsFromCGImage(bm->info(), bm->rowBytes(), bm->getPixels(), image)) { - return false; + return kFailure; } CGImageAlphaInfo info = CGImageGetAlphaInfo(image); @@ -162,7 +162,7 @@ bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { } bm->setAlphaType(kUnpremul_SkAlphaType); } - return true; + return kSuccess; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/ports/SkImageDecoder_WIC.cpp b/src/ports/SkImageDecoder_WIC.cpp index 3309af4685..0c109a276d 100644 --- a/src/ports/SkImageDecoder_WIC.cpp +++ b/src/ports/SkImageDecoder_WIC.cpp @@ -67,7 +67,7 @@ public: bool decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, Format* format) const; protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE; + virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE; }; struct FormatConversion { @@ -92,7 +92,7 @@ static SkImageDecoder::Format GuidContainerFormat_to_Format(REFGUID guid) { return SkImageDecoder::kUnknown_Format; } -bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { +SkImageDecoder::Result SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { WICModes wicMode; switch (mode) { case SkImageDecoder::kDecodeBounds_Mode: @@ -102,7 +102,7 @@ bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { wicMode = kDecodePixels_WICMode; break; } - return this->decodeStream(stream, bm, wicMode, NULL); + return this->decodeStream(stream, bm, wicMode, NULL) ? kSuccess : kFailure; } bool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, diff --git a/src/ports/SkImageDecoder_empty.cpp b/src/ports/SkImageDecoder_empty.cpp index 7824732bb9..722b7d45f8 100644 --- a/src/ports/SkImageDecoder_empty.cpp +++ b/src/ports/SkImageDecoder_empty.cpp @@ -32,8 +32,8 @@ bool SkImageDecoder::DecodeFile(const char[], SkBitmap*, SkColorType, Mode, Form return false; } -bool SkImageDecoder::decode(SkStream*, SkBitmap*, SkColorType, Mode) { - return false; +SkImageDecoder::Result SkImageDecoder::decode(SkStream*, SkBitmap*, SkColorType, Mode) { + return kFailure; } bool SkImageDecoder::DecodeStream(SkStreamRewindable*, SkBitmap*, SkColorType, Mode, Format*) { diff --git a/tests/ImageDecodingTest.cpp b/tests/ImageDecodingTest.cpp index 30665a6f8e..762852d62a 100644 --- a/tests/ImageDecodingTest.cpp +++ b/tests/ImageDecodingTest.cpp @@ -93,7 +93,7 @@ static void compare_unpremul(skiatest::Reporter* reporter, const SkString& filen } bool success = decoder->decode(&stream, &bm8888, kN32_SkColorType, - SkImageDecoder::kDecodePixels_Mode); + SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure; if (!success) { return; } @@ -106,7 +106,7 @@ static void compare_unpremul(skiatest::Reporter* reporter, const SkString& filen decoder->setRequireUnpremultipliedColors(true); success = decoder->decode(&stream, &bm8888Unpremul, kN32_SkColorType, - SkImageDecoder::kDecodePixels_Mode); + SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure; if (!success) { return; } @@ -812,7 +812,7 @@ DEF_TEST(ImageDecoding_JpegOverwrite, r) { decoder->setSampleSize(2); SkBitmap bitmap; bool success = decoder->decode(stream, &bitmap, kRGB_565_SkColorType, - SkImageDecoder::kDecodePixels_Mode); + SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure; REPORTER_ASSERT(r, success); REPORTER_ASSERT(r, !allocator->ready()); // Decoder used correct memory REPORTER_ASSERT(r, sentinal == pixels[pixelCount]); |