• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "effect/color_matrix.h"
17 
18 #include <securec.h>
19 
20 #include "utils/log.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 namespace Drawing {
25 // Hue RGB constant
26 constexpr static float HUE_R = 0.213f;
27 constexpr static float HUE_G = 0.715f;
28 constexpr static float HUE_B = 0.072f;
29 
ColorMatrix()30 ColorMatrix::ColorMatrix() noexcept
31 {
32     SetIdentity();
33 }
34 
~ColorMatrix()35 ColorMatrix::~ColorMatrix() {}
36 
SetIdentity()37 void ColorMatrix::SetIdentity()
38 {
39     for (size_t i = 0; i < MATRIX_SIZE; i = i + 6) {
40         array_[i] = 1; // identity matrix, the value of the elements on the main diagonal is 1
41     }
42 }
43 
SetArray(const scalar src[MATRIX_SIZE])44 void ColorMatrix::SetArray(const scalar src[MATRIX_SIZE])
45 {
46     auto ret = memcpy_s(array_, sizeof(array_), src, sizeof(array_));
47     if (ret != EOK) {
48         LOGE("Drawing: ColorMatrix memcpy_s failed");
49     }
50 }
51 
GetArray(scalar dst[MATRIX_SIZE]) const52 void ColorMatrix::GetArray(scalar dst[MATRIX_SIZE]) const
53 {
54     auto ret = memcpy_s(dst, sizeof(array_), array_, sizeof(array_));
55     if (ret != EOK) {
56         LOGE("Drawing: ColorMatrix memcpy_s failed");
57     }
58 }
59 
SetConcat(const ColorMatrix & m1,const ColorMatrix & m2)60 void ColorMatrix::SetConcat(const ColorMatrix& m1, const ColorMatrix& m2)
61 {
62     scalar tmp[MATRIX_SIZE] = { 0 };
63     scalar* target;
64 
65     if (array_ == m1.array_ || array_ == m2.array_) {
66         target = tmp;
67     } else {
68         target = array_;
69     }
70 
71     int index = 0;
72     for (int j = 0; j < MATRIX_SIZE; j = j + 5) {
73         for (int i = 0; i < 4; i++) { // Color matrix is a 4x5 float type matrix.
74             target[index++] = m1.array_[j + 0] * m2.array_[i + 0] + m1.array_[j + 1] * m2.array_[i + 5] +
75                 m1.array_[j + 2] * m2.array_[i + 10] + m1.array_[j + 3] * m2.array_[i + 15];
76         }
77         target[index++] = m1.array_[j + 0] * m2.array_[4] + m1.array_[j + 1] * m2.array_[9] +
78             m1.array_[j + 2] * m2.array_[14] + m1.array_[j + 3] * m2.array_[19] + m1.array_[j + 4];
79     }
80 
81     if (target != array_) {
82         auto ret = memcpy_s(array_, sizeof(array_), target, sizeof(array_));
83         if (ret != EOK) {
84             LOGE("Drawing: ColorMatrix memcpy_s failed");
85         }
86     }
87 }
88 
PreConcat(const ColorMatrix & m)89 void ColorMatrix::PreConcat(const ColorMatrix& m)
90 {
91     SetConcat(*this, m);
92 }
93 
PostConcat(const ColorMatrix & m)94 void ColorMatrix::PostConcat(const ColorMatrix& m)
95 {
96     SetConcat(m, *this);
97 }
98 
SetScale(scalar sr,scalar sg,scalar sb,scalar sa)99 void ColorMatrix::SetScale(scalar sr, scalar sg, scalar sb, scalar sa)
100 {
101     auto ret = memset_s(array_, sizeof(array_), 0, sizeof(array_));
102     if (ret != EOK) {
103         LOGE("Drawing: ColorMatrix memset_s failed");
104         return;
105     }
106     array_[0] = sr;  // red vector scale
107     array_[6] = sg;  // green vector scale
108     array_[12] = sb; // blue vector scale
109     array_[18] = sa; // alpha vetor scale
110 }
111 
SetSaturation(scalar sat)112 void ColorMatrix::SetSaturation(scalar sat)
113 {
114     auto ret = memset_s(array_, sizeof(array_), 0, sizeof(array_));
115     if (ret != EOK) {
116         LOGE("Drawing: ColorMatrix memset_s failed");
117         return;
118     }
119 
120     const float R = HUE_R * (1 - sat);
121     const float G = HUE_G * (1 - sat);
122     const float B = HUE_B * (1 - sat);
123 
124     // red channel
125     array_[SCALE_FACTOR_FOR_R] = R + sat;
126     array_[G_FACTOR_FOR_R] = G;
127     array_[B_FACTOR_FOR_R] = B;
128     // green channel
129     array_[R_FACTOR_FOR_G] = R;
130     array_[SCALE_FACTOR_FOR_G] = G + sat;
131     array_[B_FACTOR_FOR_G] = B;
132     // blue channel
133     array_[R_FACTOR_FOR_B] = R;
134     array_[G_FACTOR_FOR_B] = G;
135     array_[SCALE_FACTOR_FOR_B] = B + sat;
136     // alpha vetor scale
137     array_[SCALE_FACTOR_FOR_A] = 1;
138 }
139 } // namespace Drawing
140 } // namespace Rosen
141 } // namespace OHOS
142