/* libs/graphics/sgl/SkBitmapSampler.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

#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:
        SkASSERT(!"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:
                SkASSERT(!"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:
                SkASSERT(!"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:
                SkASSERT(!"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:
        SkASSERT(!"unknown device");
    }
    return SkNEW_ARGS(SkNullBitmapSampler, (bm, doFilter, tmx, tmy));
}

