bool DecodingImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { if (NULL == pixels) { return false; } if (fInfo != info) { // The caller has specified a different info. This is an // error for this kind of SkImageGenerator. Use the Options // to change the settings. return false; } if (info.minRowBytes() > rowBytes) { // The caller has specified a bad rowBytes. return false; } SkAssertResult(fStream->rewind()); SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); if (NULL == decoder.get()) { return false; } decoder->setDitherImage(fDitherImage); decoder->setSampleSize(fSampleSize); decoder->setRequireUnpremultipliedColors( info.fAlphaType == kUnpremul_SkAlphaType); SkBitmap bitmap; TargetAllocator allocator(fInfo, pixels, rowBytes); decoder->setAllocator(&allocator); // TODO: need to be able to pass colortype directly to decoder SkBitmap::Config legacyConfig = SkColorTypeToBitmapConfig(info.colorType()); bool success = decoder->decode(fStream, &bitmap, legacyConfig, SkImageDecoder::kDecodePixels_Mode); decoder->setAllocator(NULL); if (!success) { return false; } if (allocator.isReady()) { // Did not use pixels! SkBitmap bm; SkASSERT(bitmap.canCopyTo(info.colorType())); bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator); if (!copySuccess || allocator.isReady()) { SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed."); // Earlier we checked canCopyto(); we expect consistency. return false; } SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); } else { SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); } return true; }
// A contructor-type function that returns NULL on failure. This // prevents the returned SkImageGenerator from ever being in a bad // state. Called by both Create() functions SkImageGenerator* CreateDecodingImageGenerator( SkData* data, SkStreamRewindable* stream, const SkDecodingImageGenerator::Options& opts) { SkASSERT(stream); SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. if (opts.fUseRequestedColorType && (kIndex_8_SkColorType == opts.fRequestedColorType)) { // We do not support indexed color with SkImageGenerators, return NULL; } SkAssertResult(autoStream->rewind()); SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream)); if (NULL == decoder.get()) { return NULL; } SkBitmap bitmap; decoder->setSampleSize(opts.fSampleSize); decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul); if (!decoder->decode(stream, &bitmap, SkImageDecoder::kDecodeBounds_Mode)) { return NULL; } if (bitmap.config() == SkBitmap::kNo_Config) { return NULL; } SkImageInfo info = bitmap.info(); if (!opts.fUseRequestedColorType) { // Use default if (kIndex_8_SkColorType == bitmap.colorType()) { // We don't support kIndex8 because we don't support // colortables in this workflow. info.fColorType = kN32_SkColorType; } } else { if (!bitmap.canCopyTo(opts.fRequestedColorType)) { SkASSERT(bitmap.colorType() != opts.fRequestedColorType); return NULL; // Can not translate to needed config. } info.fColorType = opts.fRequestedColorType; } if (opts.fRequireUnpremul && info.fAlphaType != kOpaque_SkAlphaType) { info.fAlphaType = kUnpremul_SkAlphaType; } return SkNEW_ARGS(DecodingImageGenerator, (data, autoStream.detach(), info, opts.fSampleSize, opts.fDitherImage)); }