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

#include "SkData.h"
#include "SkMallocPixelRef.h"
#include "Test.h"

static void delete_uint8_proc(void* ptr, void*) {
    delete[] static_cast<uint8_t*>(ptr);
}

static void set_to_one_proc(void*, void* context) {
    *(static_cast<int*>(context)) = 1;
}

/**
 *  This test contains basic sanity checks concerning SkMallocPixelRef.
 */
DEF_TEST(MallocPixelRef, reporter) {
    REPORTER_ASSERT(reporter, true);
    SkImageInfo info = SkImageInfo::MakeN32Premul(10, 13);
    {
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewAllocate(info, info.minRowBytes() - 1, NULL));
        // rowbytes too small.
        REPORTER_ASSERT(reporter, NULL == pr.get());
    }
    {
        size_t rowBytes = info.minRowBytes() - 1;
        size_t size = info.getSafeSize(rowBytes);
        void* addr = sk_malloc_throw(size);
        SkAutoDataUnref data(SkData::NewFromMalloc(addr, size));
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewWithData(info, rowBytes,
                                          NULL, data.get()));
        // rowbytes too small.
        REPORTER_ASSERT(reporter, NULL == pr.get());
    }
    {
        size_t rowBytes = info.minRowBytes() + 2;
        size_t size = info.getSafeSize(rowBytes) - 1;
        void* addr = sk_malloc_throw(size);
        SkAutoDataUnref data(SkData::NewFromMalloc(addr, size));
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewWithData(info, rowBytes, NULL,
                                          data.get()));
        // data too small.
        REPORTER_ASSERT(reporter, NULL == pr.get());
    }
    size_t rowBytes = info.minRowBytes() + 7;
    size_t size = info.getSafeSize(rowBytes) + 9;
    {
        SkAutoMalloc memory(size);
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewDirect(info, memory.get(), rowBytes, NULL));
        REPORTER_ASSERT(reporter, pr.get() != NULL);
        REPORTER_ASSERT(reporter, memory.get() == pr->pixels());
    }
    {
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewAllocate(info, rowBytes, NULL));
        REPORTER_ASSERT(reporter, pr.get() != NULL);
        REPORTER_ASSERT(reporter, NULL != pr->pixels());
    }
    {
        void* addr = static_cast<void*>(new uint8_t[size]);
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewWithProc(info, rowBytes, NULL, addr,
                                          delete_uint8_proc, NULL));
        REPORTER_ASSERT(reporter, pr.get() != NULL);
        REPORTER_ASSERT(reporter, addr == pr->pixels());
    }
    {
        int x = 0;
        SkAutoMalloc memory(size);
        REPORTER_ASSERT(reporter, memory.get() != NULL);
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewWithProc(info, rowBytes, NULL,
                                          memory.get(), set_to_one_proc,
                                          static_cast<void*>(&x)));
        REPORTER_ASSERT(reporter, pr.get() != NULL);
        REPORTER_ASSERT(reporter, memory.get() == pr->pixels());
        REPORTER_ASSERT(reporter, 0 == x);
        pr.reset(NULL);
        // make sure that set_to_one_proc was called.
        REPORTER_ASSERT(reporter, 1 == x);
    }
    {
        void* addr = static_cast<void*>(new uint8_t[size]);
        REPORTER_ASSERT(reporter, addr != NULL);
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewWithProc(info, rowBytes, NULL, addr,
                                          delete_uint8_proc, NULL));
        REPORTER_ASSERT(reporter, addr == pr->pixels());
    }
    {
        void* addr = sk_malloc_throw(size);
        SkAutoDataUnref data(SkData::NewFromMalloc(addr, size));
        REPORTER_ASSERT(reporter, data.get() != NULL);
        SkData* dataPtr = data.get();
        REPORTER_ASSERT(reporter, dataPtr->unique());
        SkAutoTUnref<SkMallocPixelRef> pr(
            SkMallocPixelRef::NewWithData(info, rowBytes, NULL, data.get()));
        REPORTER_ASSERT(reporter, !(dataPtr->unique()));
        data.reset(NULL);
        REPORTER_ASSERT(reporter, dataPtr->unique());
        REPORTER_ASSERT(reporter, dataPtr->data() == pr->pixels());
    }
}
