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

#include "Test.h"
#include "TestClassDef.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkData.h"
#include "SkDiscardableMemoryPool.h"
#include "SkImageGenerator.h"
#include "SkPaint.h"
#include "SkShader.h"
#include "SkSurface.h"
#include "SkRandom.h"
#include "SkMatrixUtils.h"

namespace {
// A BitmapFactory that always fails when asked to return pixels.
class FailureImageGenerator : public SkImageGenerator {
public:
    FailureImageGenerator() { }
    virtual ~FailureImageGenerator() { }
    virtual bool getInfo(SkImageInfo* info) {
        info->fWidth = 100;
        info->fHeight = 100;
        info->fColorType = kPMColor_SkColorType;
        info->fAlphaType = kPremul_SkAlphaType;
        return true;
    }
    virtual bool getPixels(const SkImageInfo& info,
                           void* pixels,
                           size_t rowBytes) SK_OVERRIDE {
        // this will deliberately return false if they are asking us
        // to decode into pixels.
        return false;
    }
};
}  // namespace

// crbug.com/295895
// Crashing in skia when a pixelref fails in lockPixels
//
static void test_faulty_pixelref(skiatest::Reporter* reporter) {
    // need a cache, but don't expect to use it, so the budget is not critical
    SkAutoTUnref<SkDiscardableMemoryPool> pool(SkNEW_ARGS(SkDiscardableMemoryPool,
                                                          (10 * 1000, NULL)));
    SkBitmap bm;
    bool installSuccess = SkInstallDiscardablePixelRef(SkNEW(FailureImageGenerator), &bm, pool);
    REPORTER_ASSERT(reporter, installSuccess);
    // now our bitmap has a pixelref, but we know it will fail to lock

    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(200, 200));
    SkCanvas* canvas = surface->getCanvas();

    const SkPaint::FilterLevel levels[] = {
        SkPaint::kNone_FilterLevel,
        SkPaint::kLow_FilterLevel,
        SkPaint::kMedium_FilterLevel,
        SkPaint::kHigh_FilterLevel,
    };

    SkPaint paint;
    canvas->scale(2, 2);    // need a scale, otherwise we may ignore filtering
    for (size_t i = 0; i < SK_ARRAY_COUNT(levels); ++i) {
        paint.setFilterLevel(levels[i]);
        canvas->drawBitmap(bm, 0, 0, &paint);
    }
}

///////////////////////////////////////////////////////////////////////////////

static void rand_matrix(SkMatrix* mat, SkRandom& rand, unsigned mask) {
    mat->setIdentity();
    if (mask & SkMatrix::kTranslate_Mask) {
        mat->postTranslate(rand.nextSScalar1(), rand.nextSScalar1());
    }
    if (mask & SkMatrix::kScale_Mask) {
        mat->postScale(rand.nextSScalar1(), rand.nextSScalar1());
    }
    if (mask & SkMatrix::kAffine_Mask) {
        mat->postRotate(rand.nextSScalar1() * 360);
    }
    if (mask & SkMatrix::kPerspective_Mask) {
        mat->setPerspX(rand.nextSScalar1());
        mat->setPerspY(rand.nextSScalar1());
    }
}

static void rand_size(SkISize* size, SkRandom& rand) {
    size->set(rand.nextU() & 0xFFFF, rand.nextU() & 0xFFFF);
}

static bool treat_as_sprite(const SkMatrix& mat, const SkISize& size,
                            unsigned bits) {
    return SkTreatAsSprite(mat, size.width(), size.height(), bits);
}

static void test_treatAsSprite(skiatest::Reporter* reporter) {
    const unsigned bilerBits = kSkSubPixelBitsForBilerp;

    SkMatrix mat;
    SkISize  size;
    SkRandom rand;

    // assert: translate-only no-filter can always be treated as sprite
    for (int i = 0; i < 1000; ++i) {
        rand_matrix(&mat, rand, SkMatrix::kTranslate_Mask);
        for (int j = 0; j < 1000; ++j) {
            rand_size(&size, rand);
            REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, 0));
        }
    }

    // assert: rotate/perspect is never treated as sprite
    for (int i = 0; i < 1000; ++i) {
        rand_matrix(&mat, rand, SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask);
        for (int j = 0; j < 1000; ++j) {
            rand_size(&size, rand);
            REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, 0));
            REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
        }
    }

    size.set(500, 600);

    const SkScalar tooMuchSubpixel = 100.1f;
    mat.setTranslate(tooMuchSubpixel, 0);
    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
    mat.setTranslate(0, tooMuchSubpixel);
    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));

    const SkScalar tinySubPixel = 100.02f;
    mat.setTranslate(tinySubPixel, 0);
    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
    mat.setTranslate(0, tinySubPixel);
    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));

    const SkScalar twoThirds = SK_Scalar1 * 2 / 3;
    const SkScalar bigScale = SkScalarDiv(size.width() + twoThirds, size.width());
    mat.setScale(bigScale, bigScale);
    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, false));
    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));

    const SkScalar oneThird = SK_Scalar1 / 3;
    const SkScalar smallScale = SkScalarDiv(size.width() + oneThird, size.width());
    mat.setScale(smallScale, smallScale);
    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false));
    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));

    const SkScalar oneFortyth = SK_Scalar1 / 40;
    const SkScalar tinyScale = SkScalarDiv(size.width() + oneFortyth, size.width());
    mat.setScale(tinyScale, tinyScale);
    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false));
    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
}

static void assert_ifDrawnTo(skiatest::Reporter* reporter,
                             const SkBitmap& bm, bool shouldBeDrawn) {
    for (int y = 0; y < bm.height(); ++y) {
        for (int x = 0; x < bm.width(); ++x) {
            if (shouldBeDrawn) {
                if (SK_ColorTRANSPARENT == *bm.getAddr32(x, y)) {
                    REPORTER_ASSERT(reporter, false);
                    return;
                }
            } else {
                // should not be drawn
                if (SK_ColorTRANSPARENT != *bm.getAddr32(x, y)) {
                    REPORTER_ASSERT(reporter, false);
                    return;
                }
            }
        }
    }
}

static void test_wacky_bitmapshader(skiatest::Reporter* reporter,
                                    int width, int height, bool shouldBeDrawn) {
    SkBitmap dev;
    dev.setConfig(SkBitmap::kARGB_8888_Config, 0x56F, 0x4f6);
    dev.allocPixels();
    dev.eraseColor(SK_ColorTRANSPARENT);  // necessary, so we know if we draw to it

    SkMatrix matrix;

    SkCanvas c(dev);
    matrix.setAll(-119.34097f,
                  -43.436558f,
                  93489.945f,
                  43.436558f,
                  -119.34097f,
                  123.98426f,
                  0, 0, SK_Scalar1);
    c.concat(matrix);

    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, width, height);
    bm.allocPixels();
    bm.eraseColor(SK_ColorRED);

    SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
                                               SkShader::kRepeat_TileMode);
    matrix.setAll(0.0078740157f,
                  0,
                  SkIntToScalar(249),
                  0,
                  0.0078740157f,
                  SkIntToScalar(239),
                  0, 0, SK_Scalar1);
    s->setLocalMatrix(matrix);

    SkPaint paint;
    paint.setShader(s)->unref();

    SkRect r = SkRect::MakeXYWH(681, 239, 695, 253);
    c.drawRect(r, paint);

    assert_ifDrawnTo(reporter, dev, shouldBeDrawn);
}

/*
 *  Original bug was asserting that the matrix-proc had generated a (Y) value
 *  that was out of range. This led (in the release build) to the sampler-proc
 *  reading memory out-of-bounds of the original bitmap.
 *
 *  We were numerically overflowing our 16bit coordinates that we communicate
 *  between these two procs. The fixes was in two parts:
 *
 *  1. Just don't draw bitmaps larger than 64K-1 in width or height, since we
 *     can't represent those coordinates in our transport format (yet).
 *  2. Perform an unsigned shift during the calculation, so we don't get
 *     sign-extension bleed when packing the two values (X,Y) into our 32bit
 *     slot.
 *
 *  This tests exercises the original setup, plus 3 more to ensure that we can,
 *  in fact, handle bitmaps at 64K-1 (assuming we don't exceed the total
 *  memory allocation limit).
 */
static void test_giantrepeat_crbug118018(skiatest::Reporter* reporter) {
    static const struct {
        int fWidth;
        int fHeight;
        bool fExpectedToDraw;
    } gTests[] = {
        { 0x1b294, 0x7f,  false },   // crbug 118018 (width exceeds 64K)
        { 0xFFFF, 0x7f,    true },   // should draw, test max width
        { 0x7f, 0xFFFF,    true },   // should draw, test max height
        { 0xFFFF, 0xFFFF, false },   // allocation fails (too much RAM)
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) {
        test_wacky_bitmapshader(reporter,
                                gTests[i].fWidth, gTests[i].fHeight,
                                gTests[i].fExpectedToDraw);
    }
}

///////////////////////////////////////////////////////////////////////////////

static void test_nan_antihair() {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, 20, 20);
    bm.allocPixels();

    SkCanvas canvas(bm);

    SkPath path;
    path.moveTo(0, 0);
    path.lineTo(10, SK_ScalarNaN);

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);

    // before our fix to SkScan_Antihair.cpp to check for integral NaN (0x800...)
    // this would trigger an assert/crash.
    //
    // see rev. 3558
    canvas.drawPath(path, paint);
}

static bool check_for_all_zeros(const SkBitmap& bm) {
    SkAutoLockPixels alp(bm);

    size_t count = bm.width() * bm.bytesPerPixel();
    for (int y = 0; y < bm.height(); y++) {
        const uint8_t* ptr = reinterpret_cast<const uint8_t*>(bm.getAddr(0, y));
        for (size_t i = 0; i < count; i++) {
            if (ptr[i]) {
                return false;
            }
        }
    }
    return true;
}

static const int gWidth = 256;
static const int gHeight = 256;

static void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
    bm->setConfig(config, gWidth, gHeight);
    bm->allocPixels();
    bm->eraseColor(color);
}

DEF_TEST(DrawBitmapRect, reporter) {
    SkBitmap src, dst;

    create(&src, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    create(&dst, SkBitmap::kARGB_8888_Config, 0);

    SkCanvas canvas(dst);

    SkIRect srcR = { gWidth, 0, gWidth + 16, 16 };
    SkRect  dstR = { 0, 0, SkIntToScalar(16), SkIntToScalar(16) };

    canvas.drawBitmapRect(src, &srcR, dstR, NULL);

    // ensure that we draw nothing if srcR does not intersect the bitmap
    REPORTER_ASSERT(reporter, check_for_all_zeros(dst));

    test_nan_antihair();
    test_giantrepeat_crbug118018(reporter);

    test_treatAsSprite(reporter);
    test_faulty_pixelref(reporter);
}
