
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkBitmapSampler.h"

static SkTileModeProc get_tilemode_proc(SkShader::TileMode mode)
{
    switch (mode) {
    case SkShader::kClamp_TileMode:
        return do_clamp;
    case SkShader::kRepeat_TileMode:
        return do_repeat_mod;
    case SkShader::kMirror_TileMode:
        return do_mirror_mod;
    default:
        SkDEBUGFAIL("unknown mode");
        return NULL;
    }
}

SkBitmapSampler::SkBitmapSampler(const SkBitmap& bm, bool filter,
                                 SkShader::TileMode tmx, SkShader::TileMode tmy)
    : fBitmap(bm), fFilterBitmap(filter), fTileModeX(tmx), fTileModeY(tmy)
{
    SkASSERT(bm.width() > 0 && bm.height() > 0);

    fMaxX = SkToU16(bm.width() - 1);
    fMaxY = SkToU16(bm.height() - 1);
    
    fTileProcX = get_tilemode_proc(tmx);
    fTileProcY = get_tilemode_proc(tmy);
}

void SkBitmapSampler::setPaint(const SkPaint& paint)
{
}

class SkNullBitmapSampler : public SkBitmapSampler {
public:
    SkNullBitmapSampler(const SkBitmap& bm, bool filter,
                        SkShader::TileMode tmx, SkShader::TileMode tmy)
        : SkBitmapSampler(bm, filter, tmx, tmy) {}

    virtual SkPMColor sample(SkFixed x, SkFixed y) const { return 0; }
};

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

#define BITMAP_CLASSNAME_PREFIX(name)           ARGB32##name
#define BITMAP_PIXEL_TO_PMCOLOR(bitmap, x, y)   *bitmap.getAddr32(x, y)
#include "SkBitmapSamplerTemplate.h"

#include "SkColorPriv.h"

#define BITMAP_CLASSNAME_PREFIX(name)           RGB16##name
#define BITMAP_PIXEL_TO_PMCOLOR(bitmap, x, y)   SkPixel16ToPixel32(*bitmap.getAddr16(x, y))
#include "SkBitmapSamplerTemplate.h"

#define BITMAP_CLASSNAME_PREFIX(name)           Index8##name
#define BITMAP_PIXEL_TO_PMCOLOR(bitmap, x, y)   bitmap.getIndex8Color(x, y)
#include "SkBitmapSamplerTemplate.h"

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
///////////////// The Bilinear versions

#include "SkFilterProc.h"

class ARGB32_Bilinear_Sampler : public SkBitmapSampler {
public:
    ARGB32_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
        : SkBitmapSampler(bm, true, tmx, tmy)
    {
        fPtrProcTable = SkGetBilinearFilterPtrProcTable();
    }

    virtual SkPMColor sample(SkFixed x, SkFixed y) const
    {
        const uint32_t *p00, *p01, *p10, *p11;

        // turn pixel centers into the top-left of our filter-box
        x -= SK_FixedHalf;
        y -= SK_FixedHalf;
    
        // compute our pointers
        {
            const SkBitmap* bitmap = &fBitmap;
            int ix = x >> 16;
            int iy = y >> 16;
            
            int             maxX = fMaxX;
            SkTileModeProc  procX = fTileProcX;
            int             maxY = fMaxY;
            SkTileModeProc  procY = fTileProcY;

            int tmpx = procX(ix, maxX);
            int tmpy = procY(iy, maxY);
            p00 = bitmap->getAddr32(tmpx, tmpy);

            int tmpx1 = procX(ix + 1, maxX);
            p01 = bitmap->getAddr32(tmpx1, tmpy);

            int tmpy1 = procY(iy + 1, maxY);
            p10 = bitmap->getAddr32(tmpx, tmpy1);

            p11 = bitmap->getAddr32(tmpx1, tmpy1);
        }

        SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(fPtrProcTable, x, y);
        return proc(p00, p01, p10, p11);
    }
    
private:
    const SkFilterPtrProc* fPtrProcTable;
};

class RGB16_Bilinear_Sampler : public SkBitmapSampler {
public:
    RGB16_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
        : SkBitmapSampler(bm, true, tmx, tmy)
    {
        fProcTable = SkGetBilinearFilterProcTable();
    }

    virtual SkPMColor sample(SkFixed x, SkFixed y) const
    {
        const uint16_t *p00, *p01, *p10, *p11;

        // turn pixel centers into the top-left of our filter-box
        x -= SK_FixedHalf;
        y -= SK_FixedHalf;
    
        // compute our pointers
        {
            const SkBitmap* bitmap = &fBitmap;
            int ix = x >> 16;
            int iy = y >> 16;
            
            int             maxX = fMaxX;
            SkTileModeProc  procX = fTileProcX;
            int             maxY = fMaxY;
            SkTileModeProc  procY = fTileProcY;

            int tmpx = procX(ix, maxX);
            int tmpy = procY(iy, maxY);
            p00 = bitmap->getAddr16(tmpx, tmpy);

            int tmpx1 = procX(ix + 1, maxX);
            p01 = bitmap->getAddr16(tmpx1, tmpy);

            int tmpy1 = procY(iy + 1, maxY);
            p10 = bitmap->getAddr16(tmpx, tmpy1);

            p11 = bitmap->getAddr16(tmpx1, tmpy1);
        }

        SkFilterProc proc = SkGetBilinearFilterProc(fProcTable, x, y);
        uint32_t c = proc(SkExpand_rgb_16(*p00), SkExpand_rgb_16(*p01),
                          SkExpand_rgb_16(*p10), SkExpand_rgb_16(*p11));

        return SkPixel16ToPixel32((uint16_t)SkCompact_rgb_16(c));
    }
    
private:
    const SkFilterProc* fProcTable;
};

// If we had a init/term method on sampler, we could avoid the per-pixel
// call to lockColors/unlockColors

class Index8_Bilinear_Sampler : public SkBitmapSampler {
public:
    Index8_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
        : SkBitmapSampler(bm, true, tmx, tmy)
    {
        fPtrProcTable = SkGetBilinearFilterPtrProcTable();
    }

    virtual SkPMColor sample(SkFixed x, SkFixed y) const
    {
        const SkBitmap* bitmap = &fBitmap;

        const uint8_t *p00, *p01, *p10, *p11;

         // turn pixel centers into the top-left of our filter-box
        x -= SK_FixedHalf;
        y -= SK_FixedHalf;
    
       // compute our pointers
        {
            int ix = x >> 16;
            int iy = y >> 16;
            
            int             maxX = fMaxX;
            SkTileModeProc  procX = fTileProcX;
            int             maxY = fMaxY;
            SkTileModeProc  procY = fTileProcY;

            int tmpx = procX(ix, maxX);
            int tmpy = procY(iy, maxY);
            p00 = bitmap->getAddr8(tmpx, tmpy);

            int tmpx1 = procX(ix + 1, maxX);
            p01 = bitmap->getAddr8(tmpx1, tmpy);

            int tmpy1 = procY(iy + 1, maxY);
            p10 = bitmap->getAddr8(tmpx, tmpy1);

            p11 = bitmap->getAddr8(tmpx1, tmpy1);
        }

        const SkPMColor* colors = bitmap->getColorTable()->lockColors();

        SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(fPtrProcTable, x, y);
        uint32_t c = proc(&colors[*p00], &colors[*p01], &colors[*p10], &colors[*p11]);

        bitmap->getColorTable()->unlockColors(false);

        return c;
    }
    
private:
    const SkFilterPtrProc* fPtrProcTable;
};

class A8_Bilinear_Sampler : public SkBitmapSampler {
public:
    A8_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
        : SkBitmapSampler(bm, true, tmx, tmy)
    {
        fProcTable = SkGetBilinearFilterProcTable();
    }

    virtual void setPaint(const SkPaint& paint)
    {
        fColor = SkPreMultiplyColor(paint.getColor());
    }

    virtual SkPMColor sample(SkFixed x, SkFixed y) const
    {
        const uint8_t *p00, *p01, *p10, *p11;

        // turn pixel centers into the top-left of our filter-box
        x -= SK_FixedHalf;
        y -= SK_FixedHalf;
    
        // compute our pointers
        {
            const SkBitmap* bitmap = &fBitmap;
            int ix = x >> 16;
            int iy = y >> 16;
            
            int             maxX = fMaxX;
            SkTileModeProc  procX = fTileProcX;
            int             maxY = fMaxY;
            SkTileModeProc  procY = fTileProcY;

            int tmpx = procX(ix, maxX);
            int tmpy = procY(iy, maxY);
            p00 = bitmap->getAddr8(tmpx, tmpy);

            int tmpx1 = procX(ix + 1, maxX);
            p01 = bitmap->getAddr8(tmpx1, tmpy);

            int tmpy1 = procY(iy + 1, maxY);
            p10 = bitmap->getAddr8(tmpx, tmpy1);

            p11 = bitmap->getAddr8(tmpx1, tmpy1);
        }

        SkFilterProc proc = SkGetBilinearFilterProc(fProcTable, x, y);
        int alpha = proc(*p00, *p01, *p10, *p11);
        return SkAlphaMulQ(fColor, SkAlpha255To256(alpha));
    }
    
private:
    const SkFilterProc* fProcTable;
    SkPMColor           fColor;
};

class A8_NoFilter_Sampler : public SkBitmapSampler {
public:
    A8_NoFilter_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
        : SkBitmapSampler(bm, false, tmx, tmy)
    {
    }

    virtual void setPaint(const SkPaint& paint)
    {
        fColor = SkPreMultiplyColor(paint.getColor());
    }

    virtual SkPMColor sample(SkFixed x, SkFixed y) const
    {
        int ix = SkFixedFloor(x);
        int iy = SkFixedFloor(y);
        
        int alpha = *fBitmap.getAddr8(fTileProcX(ix, fMaxX), fTileProcY(iy, fMaxY));
        return SkAlphaMulQ(fColor, SkAlpha255To256(alpha));
    }
    
private:
    const SkFilterProc* fProcTable;
    SkPMColor           fColor;
};

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

SkBitmapSampler* SkBitmapSampler::Create(const SkBitmap& bm, bool doFilter,
                                         SkShader::TileMode tmx,
                                         SkShader::TileMode tmy)
{
    switch (bm.getConfig()) {
    case SkBitmap::kARGB_8888_Config:
        if (doFilter)
            return SkNEW_ARGS(ARGB32_Bilinear_Sampler, (bm, tmx, tmy));

        if (tmx == tmy) {
            switch (tmx) {
            case SkShader::kClamp_TileMode:
                return SkNEW_ARGS(ARGB32_Point_Clamp_Sampler, (bm));
            case SkShader::kRepeat_TileMode:
                if (is_pow2(bm.width()) && is_pow2(bm.height()))
                    return SkNEW_ARGS(ARGB32_Point_Repeat_Pow2_Sampler, (bm));
                else
                    return SkNEW_ARGS(ARGB32_Point_Repeat_Mod_Sampler, (bm));
            case SkShader::kMirror_TileMode:
                if (is_pow2(bm.width()) && is_pow2(bm.height()))
                    return SkNEW_ARGS(ARGB32_Point_Mirror_Pow2_Sampler, (bm));
                else
                    return SkNEW_ARGS(ARGB32_Point_Mirror_Mod_Sampler, (bm));
            default:
                SkDEBUGFAIL("unknown mode");
            }
        }
        else {  // tmx != tmy
            return SkNEW_ARGS(ARGB32_Point_Sampler, (bm, tmx, tmy));
        }
        break;

    case SkBitmap::kRGB_565_Config:
        if (doFilter)
            return SkNEW_ARGS(RGB16_Bilinear_Sampler, (bm, tmx, tmy));

        if (tmx == tmy) {
            switch (tmx) {
            case SkShader::kClamp_TileMode:
                return SkNEW_ARGS(RGB16_Point_Clamp_Sampler, (bm));
            case SkShader::kRepeat_TileMode:
                if (is_pow2(bm.width()) && is_pow2(bm.height()))
                    return SkNEW_ARGS(RGB16_Point_Repeat_Pow2_Sampler, (bm));
                else
                    return SkNEW_ARGS(RGB16_Point_Repeat_Mod_Sampler, (bm));
            case SkShader::kMirror_TileMode:
                if (is_pow2(bm.width()) && is_pow2(bm.height()))
                    return SkNEW_ARGS(RGB16_Point_Mirror_Pow2_Sampler, (bm));
                else
                    return SkNEW_ARGS(RGB16_Point_Mirror_Mod_Sampler, (bm));
            default:
                SkDEBUGFAIL("unknown mode");
            }
        }
        else {  // tmx != tmy
            return SkNEW_ARGS(RGB16_Point_Sampler, (bm, tmx, tmy));
        }
        break;

    case SkBitmap::kIndex8_Config:
        if (doFilter)
            return SkNEW_ARGS(Index8_Bilinear_Sampler, (bm, tmx, tmy));

        if (tmx == tmy) {
            switch (tmx) {
            case SkShader::kClamp_TileMode:
                return SkNEW_ARGS(Index8_Point_Clamp_Sampler, (bm));
            case SkShader::kRepeat_TileMode:
                if (is_pow2(bm.width()) && is_pow2(bm.height()))
                    return SkNEW_ARGS(Index8_Point_Repeat_Pow2_Sampler, (bm));
                else
                    return SkNEW_ARGS(Index8_Point_Repeat_Mod_Sampler, (bm));
            case SkShader::kMirror_TileMode:
                if (is_pow2(bm.width()) && is_pow2(bm.height()))
                    return SkNEW_ARGS(Index8_Point_Mirror_Pow2_Sampler, (bm));
                else
                    return SkNEW_ARGS(Index8_Point_Mirror_Mod_Sampler, (bm));
            default:
                SkDEBUGFAIL("unknown mode");
            }
        }
        else {  // tmx != tmy
            return SkNEW_ARGS(Index8_Point_Sampler, (bm, tmx, tmy));
        }
        break;

    case SkBitmap::kA8_Config:
        if (doFilter)
            return SkNEW_ARGS(A8_Bilinear_Sampler, (bm, tmx, tmy));
        else
            return SkNEW_ARGS(A8_NoFilter_Sampler, (bm, tmx, tmy));
        break;

    default:
        SkDEBUGFAIL("unknown device");
    }
    return SkNEW_ARGS(SkNullBitmapSampler, (bm, doFilter, tmx, tmy));
}

