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

class ARGB32_Clamp_Bilinear_BitmapShader : public SkBitmapShader {
public:
    ARGB32_Clamp_Bilinear_BitmapShader(const SkBitmap& src)
        : SkBitmapShader(src, true,
                         SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)
    {}

    virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
};

SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
                        const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table);
SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
                        const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table)
{
    int ix = fx >> 16;
    int iy = fy >> 16;

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

    p00 = p01 = ((const SkPMColor*)((const char*)srcPixels
                                    + SkClampMax(iy, srcMaxY) * srcRB))
                                    + SkClampMax(ix, srcMaxX);

    if ((unsigned)ix < srcMaxX)
        p01 += 1;
    p10 = p00;
    p11 = p01;
    if ((unsigned)iy < srcMaxY)
    {
        p10 = (const SkPMColor*)((const char*)p10 + srcRB);
        p11 = (const SkPMColor*)((const char*)p11 + srcRB);
    }

    SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(proc_table, fx, fy);
    return proc(p00, p01, p10, p11);
}

static inline SkPMColor sample_bilerpx(SkFixed fx, unsigned srcMaxX, const SkPMColor* srcPixels,
                                       int srcRB, const SkFilterPtrProc* proc_table)
{
    int ix = fx >> 16;
    
    const SkPMColor *p00, *p01, *p10, *p11;
    
    p00 = p01 = srcPixels + SkClampMax(ix, srcMaxX);
    if ((unsigned)ix < srcMaxX)
        p01 += 1;

    p10 = (const SkPMColor*)((const char*)p00 + srcRB);
    p11 = (const SkPMColor*)((const char*)p01 + srcRB);
    
    SkFilterPtrProc proc = SkGetBilinearFilterPtrXProc(proc_table, fx);
    return proc(p00, p01, p10, p11);
}

void ARGB32_Clamp_Bilinear_BitmapShader::shadeSpan(int x, int y, SkPMColor dstC[], int count)
{
    SkASSERT(count > 0);
    
    unsigned srcScale = SkAlpha255To256(this->getPaintAlpha());

    const SkMatrix& inv = this->getTotalInverse();
    const SkBitmap& srcBitmap = this->getSrcBitmap();
    unsigned        srcMaxX = srcBitmap.width() - 1;
    unsigned        srcMaxY = srcBitmap.height() - 1;
    unsigned        srcRB = srcBitmap.rowBytes();

    const SkFilterPtrProc* proc_table = SkGetBilinearFilterPtrProcTable();
    const SkPMColor* srcPixels = (const SkPMColor*)srcBitmap.getPixels();

    if (this->getInverseClass() == kPerspective_MatrixClass)
    {
        SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
                                SkIntToScalar(y) + SK_ScalarHalf, count);

        if (256 == srcScale)
        {
            while ((count = iter.next()) != 0)
            {
                const SkFixed* srcXY = iter.getXY();
                while (--count >= 0)
                {
                    SkFixed fx = *srcXY++ - SK_FixedHalf;
                    SkFixed fy = *srcXY++ - SK_FixedHalf;
                    *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
                }
            }
        }
        else    // scale by srcScale
        {
            while ((count = iter.next()) != 0)
            {
                const SkFixed* srcXY = iter.getXY();
                while (--count >= 0)
                {
                    SkFixed fx = *srcXY++ - SK_FixedHalf;
                    SkFixed fy = *srcXY++ - SK_FixedHalf;
                    SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
                    *dstC++ = SkAlphaMulQ(c, srcScale);
                }
            }
        }
    }
    else    // linear case
    {
        SkFixed fx, fy, dx, dy;

        // now init fx, fy, dx, dy
        {
            SkPoint srcPt;
            this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
                                             SkIntToScalar(y) + SK_ScalarHalf,
                                             &srcPt);

            fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
            fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;

            if (this->getInverseClass() == kFixedStepInX_MatrixClass)
                (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
            else
            {
                dx = SkScalarToFixed(inv.getScaleX());
                dy = SkScalarToFixed(inv.getSkewY());
            }
        }

        if (dy == 0 && (unsigned)(fy >> 16) < srcMaxY)
        {
            srcPixels = (const SkPMColor*)((const char*)srcPixels + (fy >> 16) * srcRB);
            proc_table = SkGetBilinearFilterPtrProcYTable(proc_table, fy);
            if (256 == srcScale)
            {
                do {
                    *dstC++ = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
                    fx += dx;
                } while (--count != 0);
            }
            else
            {
                do {
                    SkPMColor c = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
                    *dstC++ = SkAlphaMulQ(c, srcScale);
                    fx += dx;
                } while (--count != 0);
            }
        }
        else    // dy is != 0
        {
            if (256 == srcScale)
            {
                do {
                    *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
                    fx += dx;
                    fy += dy;
                } while (--count != 0);
            }
            else
            {
                do {
                    SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
                    *dstC++ = SkAlphaMulQ(c, srcScale);
                    fx += dx;
                    fy += dy;
                } while (--count != 0);
            }
        }
    }
}

