1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/* 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2006 The Android Open Source Project 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */ 7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 8bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkImageDecoder.h" 10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkBitmap.h" 11de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com#include "SkImagePriv.h" 12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkPixelRef.h" 13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkStream.h" 14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkTemplates.h" 152c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkCanvas.h" 16bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1786dbfc4180c99e8934ac930f87c569d5babbf838robertphillips@google.comSK_DEFINE_INST_COUNT(SkImageDecoder::Peeker) 1886dbfc4180c99e8934ac930f87c569d5babbf838robertphillips@google.comSK_DEFINE_INST_COUNT(SkImageDecoder::Chooser) 1986dbfc4180c99e8934ac930f87c569d5babbf838robertphillips@google.comSK_DEFINE_INST_COUNT(SkImageDecoderFactory) 2086dbfc4180c99e8934ac930f87c569d5babbf838robertphillips@google.com 21bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; 22bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 23bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkBitmap::Config SkImageDecoder::GetDeviceConfig() 24bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return gDeviceConfig; 26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 27bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 28bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) 29bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 30bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com gDeviceConfig = config; 31bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 32bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 33bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/////////////////////////////////////////////////////////////////////////////// 34bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 35bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkImageDecoder::SkImageDecoder() 369da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com : fPeeker(NULL) 379da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com , fChooser(NULL) 389da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com , fAllocator(NULL) 399da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com , fSampleSize(1) 409da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com , fDefaultPref(SkBitmap::kNo_Config) 419da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com , fDitherImage(true) 429da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com , fUsePrefTable(false) 43746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com , fPreferQualityOverSpeed(false) 44746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com , fRequireUnpremultipliedColors(false) { 45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 46bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkImageDecoder::~SkImageDecoder() { 48919114813d58933c9d9433b141e0222c34b700b1reed@google.com SkSafeUnref(fPeeker); 49919114813d58933c9d9433b141e0222c34b700b1reed@google.com SkSafeUnref(fChooser); 50919114813d58933c9d9433b141e0222c34b700b1reed@google.com SkSafeUnref(fAllocator); 51bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 5317179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.comvoid SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) { 5417179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com if (NULL == other) { 5517179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com return; 5617179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com } 5717179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->setPeeker(fPeeker); 5817179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->setChooser(fChooser); 5917179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->setAllocator(fAllocator); 6017179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->setSampleSize(fSampleSize); 6117179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com if (fUsePrefTable) { 6217179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->setPrefConfigTable(fPrefTable); 6317179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com } else { 6417179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->fDefaultPref = fDefaultPref; 6517179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com } 6617179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->setPreferQualityOverSpeed(fPreferQualityOverSpeed); 6717179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors); 6817179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com} 6917179bf8349cf4f1448c0bd57539f1df66b485d9scroggo@google.com 70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkImageDecoder::Format SkImageDecoder::getFormat() const { 71bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return kUnknown_Format; 72bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 73bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 742c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgconst char* SkImageDecoder::getFormatName() const { 7561fb262531142b22406b2e6cfb62ec0ff8221733scroggo@google.com return GetFormatName(this->getFormat()); 7661fb262531142b22406b2e6cfb62ec0ff8221733scroggo@google.com} 7761fb262531142b22406b2e6cfb62ec0ff8221733scroggo@google.com 7861fb262531142b22406b2e6cfb62ec0ff8221733scroggo@google.comconst char* SkImageDecoder::GetFormatName(Format format) { 7961fb262531142b22406b2e6cfb62ec0ff8221733scroggo@google.com switch (format) { 8006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kUnknown_Format: 8106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "Unknown Format"; 8206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kBMP_Format: 8306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "BMP"; 8406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kGIF_Format: 8506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "GIF"; 8606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kICO_Format: 8706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "ICO"; 8806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kJPEG_Format: 8906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "JPEG"; 9006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kPNG_Format: 9106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "PNG"; 9206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kWBMP_Format: 9306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "WBMP"; 9406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case kWEBP_Format: 9506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "WEBP"; 9606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com default: 9706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com SkASSERT(!"Invalid format type!"); 9806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 9906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return "Unknown Format"; 1002c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org} 1012c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 102bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { 103bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRefCnt_SafeAssign(fPeeker, peeker); 104bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return peeker; 105bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 106bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 107bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { 108bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRefCnt_SafeAssign(fChooser, chooser); 109bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return chooser; 110bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 111bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { 113bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRefCnt_SafeAssign(fAllocator, alloc); 114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return alloc; 115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 117bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkImageDecoder::setSampleSize(int size) { 118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (size < 1) { 119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size = 1; 120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fSampleSize = size; 122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width, 125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int height) const { 126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com Chooser* chooser = fChooser; 127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (NULL == chooser) { // no chooser, we just say YES to decoding :) 129bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 130bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 131bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com chooser->begin(1); 132bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com chooser->inspect(0, config, width, height); 133bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return chooser->choose() == 0; 134bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 135bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, 137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkColorTable* ctable) const { 138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return bitmap->allocPixels(fAllocator, ctable); 139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 140bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/////////////////////////////////////////////////////////////////////////////// 142226ab004e724ca97fc0c567479b327379695092dreed@android.com 143dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.comvoid SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) { 144dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com if (NULL == pref) { 145dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com fUsePrefTable = false; 146dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com } else { 147dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com fUsePrefTable = true; 1488a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com fPrefTable.fPrefFor_8Index_NoAlpha_src = pref[0]; 1498a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com fPrefTable.fPrefFor_8Index_YesAlpha_src = pref[1]; 1508a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com fPrefTable.fPrefFor_8Gray_src = SkBitmap::kNo_Config; 1518a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com fPrefTable.fPrefFor_8bpc_NoAlpha_src = pref[4]; 1528a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com fPrefTable.fPrefFor_8bpc_YesAlpha_src = pref[5]; 153dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com } 154dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com} 155dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com 1568a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.comvoid SkImageDecoder::setPrefConfigTable(const PrefConfigTable& prefTable) { 1578a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com fUsePrefTable = true; 1588a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com fPrefTable = prefTable; 1598a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com} 1608a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com 161dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.comSkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth, 162dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com bool srcHasAlpha) const { 1638463824b653f020a0f735c56dcfb39101c6c6ca9scroggo@google.com SkBitmap::Config config = SkBitmap::kNo_Config; 164dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com 165dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com if (fUsePrefTable) { 166dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com switch (srcDepth) { 167dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com case kIndex_SrcDepth: 1688a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com config = srcHasAlpha ? fPrefTable.fPrefFor_8Index_YesAlpha_src 1698a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com : fPrefTable.fPrefFor_8Index_NoAlpha_src; 170dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com break; 1718a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com case k8BitGray_SrcDepth: 1728a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com config = fPrefTable.fPrefFor_8Gray_src; 173dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com break; 174dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com case k32Bit_SrcDepth: 1758a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com config = srcHasAlpha ? fPrefTable.fPrefFor_8bpc_YesAlpha_src 1768a37728d5c4445408c2f343f90807cc7f50d4d6escroggo@google.com : fPrefTable.fPrefFor_8bpc_NoAlpha_src; 177dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com break; 178dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com } 179dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com } else { 180dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com config = fDefaultPref; 181dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com } 182dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com 183dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com if (SkBitmap::kNo_Config == config) { 184dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com config = SkImageDecoder::GetDeviceConfig(); 185dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com } 186dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com return config; 187dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com} 188dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com 189bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, 190a80d3ddc590d6b5bd1893836f8aca89412267c39scroggo@google.com SkBitmap::Config pref, Mode mode) { 191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // we reset this to false before calling onDecode 192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fShouldCancelDecode = false; 193dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 194dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com fDefaultPref = pref; 195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1962c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // pass a temporary bitmap, so that if we return false, we are assured of 1972c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // leaving the caller's bitmap untouched. 1982c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org SkBitmap tmp; 199dcfc89cccfe82f8099ef32170d352edba9778b0freed@android.com if (!this->onDecode(stream, &tmp, mode)) { 200efc74b8af0ee522065266db255e9bc48c8ceaceereed@android.com return false; 201efc74b8af0ee522065266db255e9bc48c8ceaceereed@android.com } 202efc74b8af0ee522065266db255e9bc48c8ceaceereed@android.com bm->swap(tmp); 203efc74b8af0ee522065266db255e9bc48c8ceaceereed@android.com return true; 204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 205bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 2069da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.combool SkImageDecoder::decodeSubset(SkBitmap* bm, const SkIRect& rect, 2072c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org SkBitmap::Config pref) { 2089da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // we reset this to false before calling onDecodeSubset 2092c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org fShouldCancelDecode = false; 2102c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 2112c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org fDefaultPref = pref; 2122c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 2139da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com return this->onDecodeSubset(bm, rect); 2142c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org} 2152c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 2162c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgbool SkImageDecoder::buildTileIndex(SkStream* stream, 2172c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org int *width, int *height) { 2182c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // we reset this to false before calling onBuildTileIndex 2192c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org fShouldCancelDecode = false; 2202c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 2212c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org return this->onBuildTileIndex(stream, width, height); 2222c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org} 2232c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 2249da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.combool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, 2259da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com int dstX, int dstY, int width, int height, 2269da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com int srcX, int srcY) { 2272c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org int w = width / sampleSize; 2282c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org int h = height / sampleSize; 2299da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com if (src->getConfig() == SkBitmap::kIndex8_Config) { 2309da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // kIndex8 does not allow drawing via an SkCanvas, as is done below. 2319da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // Instead, use extractSubset. Note that this shares the SkPixelRef and 2329da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // SkColorTable. 2339da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // FIXME: Since src is discarded in practice, this holds on to more 2349da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // pixels than is strictly necessary. Switch to a copy if memory 2359da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // savings are more important than speed here. This also means 2369da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // that the pixels in dst can not be reused (though there is no 2379da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com // allocation, which was already done on src). 2389da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com int x = (dstX - srcX) / sampleSize; 2399da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com int y = (dstY - srcY) / sampleSize; 2409da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com SkIRect subset = SkIRect::MakeXYWH(x, y, w, h); 2419da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com return src->extractSubset(dst, subset); 2429da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com } 2432c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // if the destination has no pixels then we must allocate them. 2442c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org if (dst->isNull()) { 2452c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org dst->setConfig(src->getConfig(), w, h); 2462c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org dst->setIsOpaque(src->isOpaque()); 2472c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 2482c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org if (!this->allocPixelRef(dst, NULL)) { 2492c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); 2509da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com return false; 2512c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org } 2522c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org } 2532c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // check to see if the destination is large enough to decode the desired 2542c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // region. If this assert fails we will just draw as much of the source 2552c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // into the destination that we can. 2569da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com if (dst->width() < w || dst->height() < h) { 2579da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com SkDEBUGF(("SkImageDecoder::cropBitmap does not have a large enough bitmap.\n")); 2589da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com } 2592c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 2602c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // Set the Src_Mode for the paint to prevent transparency issue in the 2612c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org // dest in the event that the dest was being re-used. 2622c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org SkPaint paint; 2632c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org paint.setXfermodeMode(SkXfermode::kSrc_Mode); 2642c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 2652c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org SkCanvas canvas(*dst); 2662c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org canvas.drawSprite(*src, (srcX - dstX) / sampleSize, 2672c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org (srcY - dstY) / sampleSize, 2682c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org &paint); 2699da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com return true; 2702c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org} 2712c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org 272bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/////////////////////////////////////////////////////////////////////////////// 273bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 274bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, 275664ff1bdb098df3b56e398f74af63519fa756fdcreed@android.com SkBitmap::Config pref, Mode mode, Format* format) { 276bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(file); 277bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(bm); 278bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 279772e57c160af54b9143c131f6fb9e50f7034a54dmike@reedtribe.org SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(file)); 280772e57c160af54b9143c131f6fb9e50f7034a54dmike@reedtribe.org if (stream.get()) { 281772e57c160af54b9143c131f6fb9e50f7034a54dmike@reedtribe.org if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) { 282bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bm->pixelRef()->setURI(file); 2830ade2b116178656f2f0ca3cfafa05b76ad19703ctomhudson@google.com return true; 284bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 285bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 286bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 287bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 288bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 289bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, 290664ff1bdb098df3b56e398f74af63519fa756fdcreed@android.com SkBitmap::Config pref, Mode mode, Format* format) { 291bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (0 == size) { 292bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 293bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 294bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(buffer); 295bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 296bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkMemoryStream stream(buffer, size); 297664ff1bdb098df3b56e398f74af63519fa756fdcreed@android.com return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); 298bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 299bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 30082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com/** 30182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * Special allocator used by DecodeMemoryToTarget. Uses preallocated memory 30282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * provided if the bm is 8888. Otherwise, uses a heap allocator. The same 30382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * allocator will be used again for a copy to 8888, when the preallocated 30482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * memory will be used. 30582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com */ 30682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.comclass TargetAllocator : public SkBitmap::HeapAllocator { 307de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 308de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.compublic: 309de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com TargetAllocator(void* target) 310de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com : fTarget(target) {} 311de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 312de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE { 31382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // If the config is not 8888, allocate a pixelref using the heap. 31482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // fTarget will be used to store the final pixels when copied to 31582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // 8888. 31682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (bm->config() != SkBitmap::kARGB_8888_Config) { 31782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return INHERITED::allocPixelRef(bm, ct); 31882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 31982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // In kARGB_8888_Config, there is no colortable. 320de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com SkASSERT(NULL == ct); 321de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com bm->setPixels(fTarget); 322de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com return true; 323de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com } 324de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 325de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.comprivate: 326de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com void* fTarget; 32782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com typedef SkBitmap::HeapAllocator INHERITED; 328de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com}; 329de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 33082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com/** 33182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * Helper function for DecodeMemoryToTarget. DecodeMemoryToTarget wants 33282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * 8888, so set the config to it. All parameters must not be null. 33382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @param decoder Decoder appropriate for this stream. 33482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @param stream Rewound stream to the encoded data. 33582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @param bitmap On success, will have its bounds set to the bounds of the 33682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * encoded data, and its config set to 8888. 33782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @return True if the bounds were decoded and the bitmap is 8888 or can be 33882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * copied to 8888. 33982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com */ 34082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.comstatic bool decode_bounds_to_8888(SkImageDecoder* decoder, SkStream* stream, 34182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkBitmap* bitmap) { 34282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(decoder != NULL); 34382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(stream != NULL); 34482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(bitmap != NULL); 34582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 34682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (!decoder->decode(stream, bitmap, SkImageDecoder::kDecodeBounds_Mode)) { 34782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return false; 34882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 34982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 35082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (bitmap->config() == SkBitmap::kARGB_8888_Config) { 35182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return true; 35282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 35382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 35482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)) { 35582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return false; 35682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 35782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 35882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(), bitmap->height()); 35982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return true; 36082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com} 36182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 36282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com/** 36382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * Helper function for DecodeMemoryToTarget. Decodes the stream into bitmap, and if 36482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * the bitmap is not 8888, then it is copied to 8888. Either way, the end result has 36582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * its pixels stored in target. All parameters must not be null. 36682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @param decoder Decoder appropriate for this stream. 36782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @param stream Rewound stream to the encoded data. 36882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @param bitmap On success, will contain the decoded image, with its pixels stored 36982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * at target. 37082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @param target Preallocated memory for storing pixels. 37182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com * @return bool Whether the decode (and copy, if necessary) succeeded. 37282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com */ 37382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.comstatic bool decode_pixels_to_8888(SkImageDecoder* decoder, SkStream* stream, 37482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkBitmap* bitmap, void* target) { 37582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(decoder != NULL); 37682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(stream != NULL); 37782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(bitmap != NULL); 37882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(target != NULL); 37982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 38082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com TargetAllocator allocator(target); 38182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com decoder->setAllocator(&allocator); 38282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 38382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com bool success = decoder->decode(stream, bitmap, SkImageDecoder::kDecodePixels_Mode); 38482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com decoder->setAllocator(NULL); 38582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 38682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (!success) { 38782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return false; 38882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 38982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 39082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (bitmap->config() == SkBitmap::kARGB_8888_Config) { 39182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return true; 39282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 39382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 39482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkBitmap bm8888; 39582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (!bitmap->copyTo(&bm8888, SkBitmap::kARGB_8888_Config, &allocator)) { 39682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return false; 39782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 39882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 39982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com bitmap->swap(bm8888); 40082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return true; 40182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com} 40282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 403de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.combool SkImageDecoder::DecodeMemoryToTarget(const void* buffer, size_t size, 404de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com SkImage::Info* info, 405de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com const SkBitmapFactory::Target* target) { 406de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com if (NULL == info) { 407de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com return false; 408de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com } 40982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 410de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com // FIXME: Just to get this working, implement in terms of existing 411de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com // ImageDecoder calls. 412de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com SkBitmap bm; 413de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com SkMemoryStream stream(buffer, size); 414de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); 41582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (NULL == decoder.get()) { 41682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return false; 41782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 418de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 41982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (!decode_bounds_to_8888(decoder.get(), &stream, &bm)) { 42082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return false; 42182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 422de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 42382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config); 424de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 42582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // Now set info properly. 42682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // Since Config is SkBitmap::kARGB_8888_Config, SkBitmapToImageInfo 42782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // will always succeed. 42882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkAssertResult(SkBitmapToImageInfo(bm, info)); 42982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 43082b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (NULL == target) { 43182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return true; 43282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 433de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 43482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (target->fRowBytes != SkToU32(bm.rowBytes())) { 43582b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com if (target->fRowBytes < SkImageMinRowBytes(*info)) { 43682b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkASSERT(!"Desired row bytes is too small"); 43782b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return false; 43882b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com } 43982b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com bm.setConfig(bm.config(), bm.width(), bm.height(), target->fRowBytes); 440de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com } 44182b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com 44282b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com // SkMemoryStream.rewind() will always return true. 44382b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com SkAssertResult(stream.rewind()); 44482b9077620425e33e17e96bf5a15f36929eb8436scroggo@google.com return decode_pixels_to_8888(decoder.get(), &stream, &bm, target->fAddr); 445de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com} 446de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 447de5698ff718963fd47fbb9d100ab51af35247bb6scroggo@google.com 448bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, 449664ff1bdb098df3b56e398f74af63519fa756fdcreed@android.com SkBitmap::Config pref, Mode mode, Format* format) { 450bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(stream); 451bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(bm); 452bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 453bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool success = false; 454bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkImageDecoder* codec = SkImageDecoder::Factory(stream); 455bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 456bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (NULL != codec) { 457bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com success = codec->decode(stream, bm, pref, mode); 458664ff1bdb098df3b56e398f74af63519fa756fdcreed@android.com if (success && format) { 459664ff1bdb098df3b56e398f74af63519fa756fdcreed@android.com *format = codec->getFormat(); 46006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (kUnknown_Format == *format) { 46106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (stream->rewind()) { 46206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com *format = GetStreamFormat(stream); 46306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 46406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 465664ff1bdb098df3b56e398f74af63519fa756fdcreed@android.com } 466bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com delete codec; 467bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 468bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return success; 469bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 470