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