1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "include/effects/SkColorMatrix.h"
9 #include "src/core/SkYUVMath.h"
10
11 enum SkYUVColorSpace : int;
12
RGBtoYUV(SkYUVColorSpace cs)13 SkColorMatrix SkColorMatrix::RGBtoYUV(SkYUVColorSpace cs) {
14 SkColorMatrix m;
15 SkColorMatrix_RGB2YUV(cs, m.fMat.data());
16 return m;
17 }
18
YUVtoRGB(SkYUVColorSpace cs)19 SkColorMatrix SkColorMatrix::YUVtoRGB(SkYUVColorSpace cs) {
20 SkColorMatrix m;
21 SkColorMatrix_YUV2RGB(cs, m.fMat.data());
22 return m;
23 }
24
25 enum {
26 kR_Scale = 0,
27 kG_Scale = 6,
28 kB_Scale = 12,
29 kA_Scale = 18,
30
31 kR_Trans = 4,
32 kG_Trans = 9,
33 kB_Trans = 14,
34 kA_Trans = 19,
35 };
36
set_concat(float result[20],const float outer[20],const float inner[20])37 static void set_concat(float result[20], const float outer[20], const float inner[20]) {
38 float tmp[20];
39 float* target;
40
41 if (outer == result || inner == result) {
42 target = tmp; // will memcpy answer when we're done into result
43 } else {
44 target = result;
45 }
46
47 int index = 0;
48 for (int j = 0; j < 20; j += 5) {
49 for (int i = 0; i < 4; i++) {
50 target[index++] = outer[j + 0] * inner[i + 0] +
51 outer[j + 1] * inner[i + 5] +
52 outer[j + 2] * inner[i + 10] +
53 outer[j + 3] * inner[i + 15];
54 }
55 target[index++] = outer[j + 0] * inner[4] +
56 outer[j + 1] * inner[9] +
57 outer[j + 2] * inner[14] +
58 outer[j + 3] * inner[19] +
59 outer[j + 4];
60 }
61
62 if (target != result) {
63 std::copy_n(target, 20, result);
64 }
65 }
66
setIdentity()67 void SkColorMatrix::setIdentity() {
68 fMat.fill(0.0f);
69 fMat[kR_Scale] = fMat[kG_Scale] = fMat[kB_Scale] = fMat[kA_Scale] = 1;
70 }
71
setScale(float rScale,float gScale,float bScale,float aScale)72 void SkColorMatrix::setScale(float rScale, float gScale, float bScale, float aScale) {
73 fMat.fill(0.0f);
74 fMat[kR_Scale] = rScale;
75 fMat[kG_Scale] = gScale;
76 fMat[kB_Scale] = bScale;
77 fMat[kA_Scale] = aScale;
78 }
79
postTranslate(float dr,float dg,float db,float da)80 void SkColorMatrix::postTranslate(float dr, float dg, float db, float da) {
81 fMat[kR_Trans] += dr;
82 fMat[kG_Trans] += dg;
83 fMat[kB_Trans] += db;
84 fMat[kA_Trans] += da;
85 }
86
87 ///////////////////////////////////////////////////////////////////////////////
88
setConcat(const SkColorMatrix & matA,const SkColorMatrix & matB)89 void SkColorMatrix::setConcat(const SkColorMatrix& matA, const SkColorMatrix& matB) {
90 set_concat(fMat.data(), matA.fMat.data(), matB.fMat.data());
91 }
92
93 ///////////////////////////////////////////////////////////////////////////////
94
setrow(float row[],float r,float g,float b)95 static void setrow(float row[], float r, float g, float b) {
96 row[0] = r;
97 row[1] = g;
98 row[2] = b;
99 }
100
101 static const float kHueR = 0.213f;
102 static const float kHueG = 0.715f;
103 static const float kHueB = 0.072f;
104
setSaturation(float sat)105 void SkColorMatrix::setSaturation(float sat) {
106 fMat.fill(0.0f);
107
108 const float R = kHueR * (1 - sat);
109 const float G = kHueG * (1 - sat);
110 const float B = kHueB * (1 - sat);
111
112 setrow(fMat.data() + 0, R + sat, G, B);
113 setrow(fMat.data() + 5, R, G + sat, B);
114 setrow(fMat.data() + 10, R, G, B + sat);
115 fMat[kA_Scale] = 1;
116 }
117