1096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger/* 2096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Copyright 2012 Google Inc. 3096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 4096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 5096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * found in the LICENSE file. 6096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */ 7096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 8096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkBitmapFactory.h" 9096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 10096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkBitmap.h" 11096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkData.h" 12096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkImageCache.h" 13096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkImagePriv.h" 14096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkLazyPixelRef.h" 15096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSK_DEFINE_INST_COUNT(SkBitmapFactory::CacheSelector) 1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 18096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkBitmapFactory::SkBitmapFactory(SkBitmapFactory::DecodeProc proc) 19096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger : fDecodeProc(proc) 20096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger , fImageCache(NULL) 21096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger , fCacheSelector(NULL) { 22096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkASSERT(fDecodeProc != NULL); 23096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 24096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 25096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkBitmapFactory::~SkBitmapFactory() { 26096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkSafeUnref(fImageCache); 27096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkSafeUnref(fCacheSelector); 28096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 29096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 30096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergervoid SkBitmapFactory::setImageCache(SkImageCache *cache) { 31096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkRefCnt_SafeAssign(fImageCache, cache); 32096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (cache != NULL) { 33096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkSafeUnref(fCacheSelector); 34096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fCacheSelector = NULL; 35096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 36096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 37096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 38096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergervoid SkBitmapFactory::setCacheSelector(CacheSelector* selector) { 39096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkRefCnt_SafeAssign(fCacheSelector, selector); 40096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (selector != NULL) { 41096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkSafeUnref(fImageCache); 42096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fImageCache = NULL; 43096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 44096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 45096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool SkBitmapFactory::installPixelRef(SkData* data, SkBitmap* dst) { 47096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL == data || 0 == data->size() || dst == NULL) { 48096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 49096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 50096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 51096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkImage::Info info; 52096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!fDecodeProc(data->data(), data->size(), &info, NULL)) { 53096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 54096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 55096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 56096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger bool isOpaque = false; 57096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque); 58096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 59096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger Target target; 60096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // FIMXE: There will be a problem if this rowbytes is calculated differently from 61096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // in SkLazyPixelRef. 62096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger target.fRowBytes = SkImageMinRowBytes(info); 63096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 64096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger dst->setConfig(config, info.fWidth, info.fHeight, target.fRowBytes); 65096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger dst->setIsOpaque(isOpaque); 66096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 67096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // fImageCache and fCacheSelector are mutually exclusive. 68096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkASSERT(NULL == fImageCache || NULL == fCacheSelector); 69096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 70096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkImageCache* cache = NULL == fCacheSelector ? fImageCache : fCacheSelector->selectCache(info); 71096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 72096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (cache != NULL) { 73096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // Now set a new LazyPixelRef on dst. 74096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkAutoTUnref<SkLazyPixelRef> lazyRef(SkNEW_ARGS(SkLazyPixelRef, 75096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger (data, fDecodeProc, cache))); 76096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger dst->setPixelRef(lazyRef); 77096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return true; 78096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } else { 79096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger dst->allocPixels(); 80096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger target.fAddr = dst->getPixels(); 81096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return fDecodeProc(data->data(), data->size(), &info, &target); 82096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 83096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 84