xref: /aosp_15_r20/external/skia/src/effects/SkColorMatrix.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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