Home | History | Annotate | Download | only in utils
      1 #include "SkColorMatrix.h"
      2 
      3 #define kRScale     0
      4 #define kGScale     6
      5 #define kBScale     12
      6 #define kAScale     18
      7 
      8 void SkColorMatrix::setIdentity() {
      9     memset(fMat, 0, sizeof(fMat));
     10     fMat[kRScale] = fMat[kGScale] = fMat[kBScale] = fMat[kAScale] = SK_Scalar1;
     11 }
     12 
     13 void SkColorMatrix::setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
     14                              SkScalar aScale) {
     15     memset(fMat, 0, sizeof(fMat));
     16     fMat[kRScale] = rScale;
     17     fMat[kGScale] = gScale;
     18     fMat[kBScale] = bScale;
     19     fMat[kAScale] = aScale;
     20 }
     21 
     22 ///////////////////////////////////////////////////////////////////////////////
     23 
     24 void SkColorMatrix::setRotate(Axis axis, SkScalar degrees) {
     25     SkScalar S, C;
     26 
     27     S = SkScalarSinCos(SkDegreesToRadians(degrees), &C);
     28 
     29     this->setSinCos(axis, S, C);
     30 }
     31 
     32 void SkColorMatrix::setSinCos(Axis axis, SkScalar sine, SkScalar cosine) {
     33     SkASSERT((unsigned)axis < 3);
     34 
     35     static const uint8_t gRotateIndex[] = {
     36         6, 7, 11, 12,
     37         0, 10, 2, 12,
     38         0, 1,  5,  6,
     39     };
     40     const uint8_t* index = gRotateIndex + axis * 4;
     41 
     42     this->setIdentity();
     43     fMat[index[0]] = cosine;
     44     fMat[index[1]] = sine;
     45     fMat[index[2]] = -sine;
     46     fMat[index[3]] = cosine;
     47 }
     48 
     49 void SkColorMatrix::preRotate(Axis axis, SkScalar degrees) {
     50     SkColorMatrix tmp;
     51     tmp.setRotate(axis, degrees);
     52     this->preConcat(tmp);
     53 }
     54 
     55 void SkColorMatrix::postRotate(Axis axis, SkScalar degrees) {
     56     SkColorMatrix tmp;
     57     tmp.setRotate(axis, degrees);
     58     this->postConcat(tmp);
     59 }
     60 
     61 ///////////////////////////////////////////////////////////////////////////////
     62 
     63 void SkColorMatrix::setConcat(const SkColorMatrix& matA,
     64                               const SkColorMatrix& matB) {
     65     SkScalar    tmp[20];
     66     SkScalar*   result = fMat;
     67 
     68     if (&matA == this || &matB == this) {
     69         result = tmp;
     70     }
     71 
     72     const SkScalar* a = matA.fMat;
     73     const SkScalar* b = matB.fMat;
     74 
     75     int index = 0;
     76     for (int j = 0; j < 20; j += 5) {
     77         for (int i = 0; i < 4; i++) {
     78             result[index++] =   SkScalarMul(a[j + 0], b[i + 0]) +
     79                                 SkScalarMul(a[j + 1], b[i + 5]) +
     80                                 SkScalarMul(a[j + 2], b[i + 10]) +
     81                                 SkScalarMul(a[j + 3], b[i + 15]);
     82         }
     83         result[index++] =   SkScalarMul(a[j + 0], b[4]) +
     84                             SkScalarMul(a[j + 1], b[9]) +
     85                             SkScalarMul(a[j + 2], b[14]) +
     86                             SkScalarMul(a[j + 3], b[19]) +
     87                             a[j + 4];
     88     }
     89 
     90     if (fMat != result) {
     91         memcpy(fMat, result, sizeof(fMat));
     92     }
     93 }
     94 
     95 ///////////////////////////////////////////////////////////////////////////////
     96 
     97 static void setrow(SkScalar row[], SkScalar r, SkScalar g, SkScalar b) {
     98     row[0] = r;
     99     row[1] = g;
    100     row[2] = b;
    101 }
    102 
    103 static const SkScalar kHueR = SkFloatToScalar(0.213f);
    104 static const SkScalar kHueG = SkFloatToScalar(0.715f);
    105 static const SkScalar kHueB = SkFloatToScalar(0.072f);
    106 
    107 void SkColorMatrix::setSaturation(SkScalar sat) {
    108     memset(fMat, 0, sizeof(fMat));
    109 
    110     const SkScalar R = SkScalarMul(kHueR, SK_Scalar1 - sat);
    111     const SkScalar G = SkScalarMul(kHueG, SK_Scalar1 - sat);
    112     const SkScalar B = SkScalarMul(kHueB, SK_Scalar1 - sat);
    113 
    114     setrow(fMat +  0, R + sat, G, B);
    115     setrow(fMat +  5, R, G + sat, B);
    116     setrow(fMat + 10, R, G, B + sat);
    117     fMat[18] = SK_Scalar1;
    118 }
    119 
    120 static const SkScalar kR2Y = SkFloatToScalar(0.299f);
    121 static const SkScalar kG2Y = SkFloatToScalar(0.587f);
    122 static const SkScalar kB2Y = SkFloatToScalar(0.114f);
    123 
    124 static const SkScalar kR2U = SkFloatToScalar(-0.16874f);
    125 static const SkScalar kG2U = SkFloatToScalar(-0.33126f);
    126 static const SkScalar kB2U = SkFloatToScalar(0.5f);
    127 
    128 static const SkScalar kR2V = SkFloatToScalar(0.5f);
    129 static const SkScalar kG2V = SkFloatToScalar(-0.41869f);
    130 static const SkScalar kB2V = SkFloatToScalar(-0.08131f);
    131 
    132 void SkColorMatrix::setRGB2YUV() {
    133     memset(fMat, 0, sizeof(fMat));
    134 
    135     setrow(fMat +  0, kR2Y, kG2Y, kB2Y);
    136     setrow(fMat +  5, kR2U, kG2U, kB2U);
    137     setrow(fMat + 10, kR2V, kG2V, kB2V);
    138     fMat[18] = SK_Scalar1;
    139 }
    140 
    141 static const SkScalar kV2R = SkFloatToScalar(1.402f);
    142 static const SkScalar kU2G = SkFloatToScalar(-0.34414f);
    143 static const SkScalar kV2G = SkFloatToScalar(-0.71414f);
    144 static const SkScalar kU2B = SkFloatToScalar(1.772f);
    145 
    146 void SkColorMatrix::setYUV2RGB() {
    147     memset(fMat, 0, sizeof(fMat));
    148 
    149     setrow(fMat +  0, SK_Scalar1, 0, kV2R);
    150     setrow(fMat +  5, SK_Scalar1, kU2G, kV2G);
    151     setrow(fMat + 10, SK_Scalar1, kU2B, 0);
    152     fMat[18] = SK_Scalar1;
    153 }
    154 
    155