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