/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBitmapFactory.h"

#include "SkBitmap.h"
#include "SkData.h"
#include "SkImageCache.h"
#include "SkImagePriv.h"
#include "SkLazyPixelRef.h"

SK_DEFINE_INST_COUNT(SkBitmapFactory::CacheSelector)

SkBitmapFactory::SkBitmapFactory(SkBitmapFactory::DecodeProc proc)
    : fDecodeProc(proc)
    , fImageCache(NULL)
    , fCacheSelector(NULL) {
    SkASSERT(fDecodeProc != NULL);
}

SkBitmapFactory::~SkBitmapFactory() {
    SkSafeUnref(fImageCache);
    SkSafeUnref(fCacheSelector);
}

void SkBitmapFactory::setImageCache(SkImageCache *cache) {
    SkRefCnt_SafeAssign(fImageCache, cache);
    if (cache != NULL) {
        SkSafeUnref(fCacheSelector);
        fCacheSelector = NULL;
    }
}

void SkBitmapFactory::setCacheSelector(CacheSelector* selector) {
    SkRefCnt_SafeAssign(fCacheSelector, selector);
    if (selector != NULL) {
        SkSafeUnref(fImageCache);
        fImageCache = NULL;
    }
}

bool SkBitmapFactory::installPixelRef(SkData* data, SkBitmap* dst) {
    if (NULL == data || 0 == data->size() || dst == NULL) {
        return false;
    }

    SkImageInfo info;
    if (!fDecodeProc(data->data(), data->size(), &info, NULL)) {
        return false;
    }

    SkBitmap::Config config = SkImageInfoToBitmapConfig(info);

    Target target;
    // FIMXE: There will be a problem if this rowbytes is calculated differently from
    // in SkLazyPixelRef.
    target.fRowBytes = SkImageMinRowBytes(info);
    dst->setConfig(config, info.fWidth, info.fHeight, target.fRowBytes, info.fAlphaType);

    // fImageCache and fCacheSelector are mutually exclusive.
    SkASSERT(NULL == fImageCache || NULL == fCacheSelector);

    SkImageCache* cache = NULL == fCacheSelector ? fImageCache : fCacheSelector->selectCache(info);

    if (cache != NULL) {
        // Now set a new LazyPixelRef on dst.
        SkAutoTUnref<SkLazyPixelRef> lazyRef(SkNEW_ARGS(SkLazyPixelRef,
                                                        (data, fDecodeProc, cache)));
        dst->setPixelRef(lazyRef);
        return true;
    } else {
        dst->allocPixels();
        target.fAddr = dst->getPixels();
        return fDecodeProc(data->data(), data->size(), &info, &target);
    }
}
