
/*
 * 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);
            }
        }
    }
}
