#include "SkColorMatrix.h"

#define kRScale     0
#define kGScale     6
#define kBScale     12
#define kAScale     18

void SkColorMatrix::setIdentity()
{
    memset(fMat, 0, sizeof(fMat));
    fMat[kRScale] = fMat[kGScale] = fMat[kBScale] = fMat[kAScale] = SK_Scalar1;
}

void SkColorMatrix::setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
                             SkScalar aScale)
{
    memset(fMat, 0, sizeof(fMat));
    fMat[kRScale] = rScale;
    fMat[kGScale] = gScale;
    fMat[kBScale] = bScale;
    fMat[kAScale] = aScale;
}

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

void SkColorMatrix::setRotate(Axis axis, SkScalar degrees)
{
    SkScalar S, C;

    S = SkScalarSinCos(SkDegreesToRadians(degrees), &C);

    this->setSinCos(axis, S, C);
}

void SkColorMatrix::setSinCos(Axis axis, SkScalar sine, SkScalar cosine)
{
    SkASSERT((unsigned)axis < 3);

    static const uint8_t gRotateIndex[] = {
        6, 7, 11, 12,
        0, 2, 15, 17,
        0, 1,  5,  6,
    };
    const uint8_t* index = gRotateIndex + axis * 4;
    
    this->setIdentity();
    fMat[index[0]] = cosine;
    fMat[index[1]] = sine;
    fMat[index[2]] = -sine;
    fMat[index[3]] = cosine;
}

void SkColorMatrix::preRotate(Axis axis, SkScalar degrees)
{
    SkColorMatrix tmp;
    tmp.setRotate(axis, degrees);
    this->preConcat(tmp);
}

void SkColorMatrix::postRotate(Axis axis, SkScalar degrees)
{
    SkColorMatrix tmp;
    tmp.setRotate(axis, degrees);
    this->postConcat(tmp);
}

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

void SkColorMatrix::setConcat(const SkColorMatrix& matA,
                              const SkColorMatrix& matB)
{
    SkScalar    tmp[20];
    SkScalar*   result = fMat;

    if (&matA == this || &matB == this)
        result = tmp;
    
    const SkScalar* a = matA.fMat;
    const SkScalar* b = matB.fMat;

    int index = 0;
    for (int j = 0; j < 20; j += 5)
    {
        for (int i = 0; i < 4; i++)
        {
            result[index++] =   SkScalarMul(a[j + 0], b[i + 0]) + 
                                SkScalarMul(a[j + 1], b[i + 5]) +
                                SkScalarMul(a[j + 2], b[i + 10]) +
                                SkScalarMul(a[j + 3], b[i + 15]);
        }
        result[index++] =   SkScalarMul(a[j + 0], b[4]) +
                            SkScalarMul(a[j + 1], b[9]) +
                            SkScalarMul(a[j + 2], b[14]) +
                            SkScalarMul(a[j + 3], b[19]) +
                            a[j + 4];
    }
    
    if (fMat != result)
        memcpy(fMat, result, sizeof(fMat));
}

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

static void setrow(SkScalar row[], SkScalar r, SkScalar g, SkScalar b)
{
    row[0] = r;
    row[1] = g;
    row[2] = b;
}

static const SkScalar kHueR = SkFloatToScalar(0.213f);
static const SkScalar kHueG = SkFloatToScalar(0.715f);
static const SkScalar kHueB = SkFloatToScalar(0.072f);

void SkColorMatrix::setSaturation(SkScalar sat)
{
    memset(fMat, 0, sizeof(fMat));

    const SkScalar R = SkScalarMul(kHueR, SK_Scalar1 - sat);
    const SkScalar G = SkScalarMul(kHueG, SK_Scalar1 - sat);
    const SkScalar B = SkScalarMul(kHueB, SK_Scalar1 - sat);

    setrow(fMat +  0, R + sat, G, B);
    setrow(fMat +  5, R, G + sat, B);
    setrow(fMat + 10, R, G, B + sat);
    fMat[18] = SK_Scalar1;
}

static const SkScalar kR2Y = SkFloatToScalar(0.299f);
static const SkScalar kG2Y = SkFloatToScalar(0.587f);
static const SkScalar kB2Y = SkFloatToScalar(0.114f);

static const SkScalar kR2U = SkFloatToScalar(-0.16874f);
static const SkScalar kG2U = SkFloatToScalar(-0.33126f);
static const SkScalar kB2U = SkFloatToScalar(0.5f);

static const SkScalar kR2V = SkFloatToScalar(0.5f);
static const SkScalar kG2V = SkFloatToScalar(-0.41869f);
static const SkScalar kB2V = SkFloatToScalar(-0.08131f);

void SkColorMatrix::setRGB2YUV()
{
    memset(fMat, 0, sizeof(fMat));
    
    setrow(fMat +  0, kR2Y, kG2Y, kB2Y);
    setrow(fMat +  5, kR2U, kG2U, kB2U);
    setrow(fMat + 10, kR2V, kG2V, kB2V);
    fMat[18] = SK_Scalar1;
}

static const SkScalar kV2R = SkFloatToScalar(1.402f);
static const SkScalar kU2G = SkFloatToScalar(-0.34414f);
static const SkScalar kV2G = SkFloatToScalar(-0.71414f);
static const SkScalar kU2B = SkFloatToScalar(1.772f);

void SkColorMatrix::setYUV2RGB()
{
    memset(fMat, 0, sizeof(fMat));
    
    setrow(fMat +  0, SK_Scalar1, 0, kV2R);
    setrow(fMat +  5, SK_Scalar1, kU2G, kV2G);
    setrow(fMat + 10, SK_Scalar1, kU2B, 0);
    fMat[18] = SK_Scalar1;
}

