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 #include "sec_comp_tool.h"
16
17 #include <cmath>
18 #include <cstdint>
19 #include "sec_comp_log.h"
20
21 namespace OHOS {
22 namespace Security {
23 namespace SecurityComponent {
24 namespace {
25 static constexpr double PI_CIRCLE = 3.1415926;
26 static constexpr double MIN_HSV_DISTANCE = 25.0;
27 static constexpr double MAX_RGB_VALUE = 255.0;
28 static constexpr uint8_t MAX_TRANSPARENT = 0x99; // 60%
29 static constexpr double ZERO_DOUBLE = 0.0;
30 static constexpr double THIRTY_ANGLE = 30.0;
31 static constexpr double SIXTY_ANGLE = 60.0;
32 static constexpr double ONE_HUNDRED_TWEENTY_ANGLE = 120.0;
33 static constexpr double ONE_HUNDRED_EIGHTY_ANGLE = 180.0;
34 static constexpr double TWO_HUNDREDS_FORTY_ANGLE = 240.0;
35 static constexpr double THREE_HUNDREDS_SIXTY_ANGLE = 360.0;
36 static constexpr double DEFAULT_R = 100.0;
37 static const uint8_t MAX_ALPHA = 0xFF;
38 static const double MIN_CONTRACST_ALPHA = 0.5;
39
40 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompTool"};
41 }
42
MaxValue(double a,double b,double c)43 static inline double MaxValue(double a, double b, double c)
44 {
45 return ((a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c));
46 }
47
MinValue(double a,double b,double c)48 static inline double MinValue(double a, double b, double c)
49 {
50 return ((a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c));
51 }
52
53 struct HsvColor {
54 double h;
55 double s;
56 double v;
57 };
58
RgbToHsv(uint8_t r,uint8_t g,uint8_t b)59 static HsvColor RgbToHsv(uint8_t r, uint8_t g, uint8_t b)
60 {
61 HsvColor hsv;
62 double red = static_cast<double>(r) / MAX_RGB_VALUE;
63 double green = static_cast<double>(g) / MAX_RGB_VALUE;
64 double blue = static_cast<double>(b) / MAX_RGB_VALUE;
65 double max = MaxValue(red, green, blue);
66 double min = MinValue(red, green, blue);
67 double delta = max - min;
68 if (max == min) {
69 hsv.h = ZERO_DOUBLE;
70 } else if (max == red) {
71 hsv.h = fmod((SIXTY_ANGLE * ((green - blue) / delta) + THREE_HUNDREDS_SIXTY_ANGLE),
72 THREE_HUNDREDS_SIXTY_ANGLE);
73 } else if (max == green) {
74 hsv.h = fmod((SIXTY_ANGLE * ((blue - red) / delta) + ONE_HUNDRED_TWEENTY_ANGLE), THREE_HUNDREDS_SIXTY_ANGLE);
75 } else if (max == blue) {
76 hsv.h = fmod((SIXTY_ANGLE * ((red - green) / delta) + TWO_HUNDREDS_FORTY_ANGLE), THREE_HUNDREDS_SIXTY_ANGLE);
77 }
78
79 if (max == 0) {
80 hsv.s = ZERO_DOUBLE;
81 } else {
82 hsv.s = delta / max;
83 }
84
85 hsv.v = max;
86 return hsv;
87 }
88
GetHsvDisX(const HsvColor & hsv,double r)89 static inline double GetHsvDisX(const HsvColor& hsv, double r)
90 {
91 return r * hsv.v * hsv.s * cos(hsv.h / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
92 }
93
GetHsvDisY(const HsvColor & hsv,double r)94 static inline double GetHsvDisY(const HsvColor& hsv, double r)
95 {
96 return r * hsv.v * hsv.s * sin(hsv.h / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
97 }
98
GetHsvDisZ(const HsvColor & hsv,double h)99 static inline double GetHsvDisZ(const HsvColor& hsv, double h)
100 {
101 return h * (1 - hsv.v);
102 }
103
HsvDistance(const HsvColor & hsv1,const HsvColor & hsv2)104 static double HsvDistance(const HsvColor& hsv1, const HsvColor& hsv2)
105 {
106 double rDef = DEFAULT_R;
107 double angle = THIRTY_ANGLE;
108 double h = rDef * cos(angle / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
109 double r = rDef * sin(angle / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
110
111 double x1 = GetHsvDisX(hsv1, r);
112 double y1 = GetHsvDisY(hsv1, r);
113 double z1 = GetHsvDisZ(hsv1, h);
114
115 double x2 = GetHsvDisX(hsv2, r);
116 double y2 = GetHsvDisY(hsv2, r);
117 double z2 = GetHsvDisZ(hsv2, h);
118
119 double dx = x1 - x2;
120 double dy = y1 - y2;
121 double dz = z1 - z2;
122
123 return sqrt((dx * dx) + (dy * dy) + (dz * dz));
124 }
125
IsColorAplhaSimilar(const SecCompColor & fgColor,const SecCompColor & bgColor)126 static bool IsColorAplhaSimilar(const SecCompColor& fgColor, const SecCompColor& bgColor)
127 {
128 double fgAlpha = static_cast<double>(fgColor.argb.alpha) / MAX_ALPHA;
129 double bgAlpha = static_cast<double>(bgColor.argb.alpha) / MAX_ALPHA;
130
131 double mixAlpha = fgAlpha + bgAlpha - fgAlpha * bgAlpha;
132 if (GreatNotEqual(bgAlpha / mixAlpha, MIN_CONTRACST_ALPHA)) {
133 SC_LOG_ERROR(LABEL, "FgAlpha=%{public}x BgAlpha=%{public}x is similar, check failed",
134 fgColor.argb.alpha, bgColor.argb.alpha);
135 return true;
136 }
137 return false;
138 }
139
IsColorSimilar(const SecCompColor & color1,const SecCompColor & color2)140 bool IsColorSimilar(const SecCompColor& color1, const SecCompColor& color2)
141 {
142 HsvColor hsv1 = RgbToHsv(color1.argb.red, color1.argb.green, color1.argb.blue);
143 HsvColor hsv2 = RgbToHsv(color2.argb.red, color2.argb.green, color2.argb.blue);
144
145 double distance = HsvDistance(hsv1, hsv2);
146 SC_LOG_DEBUG(LABEL, "Compare color %{public}x %{public}x distance %{public}f",
147 color1.value, color2.value, distance);
148 return (distance < MIN_HSV_DISTANCE) && IsColorAplhaSimilar(color1, color2);
149 }
150
IsColorTransparent(const SecCompColor & color)151 bool IsColorTransparent(const SecCompColor& color)
152 {
153 SC_LOG_DEBUG(LABEL, "Color %{public}x alpha %{public}x", color.value, color.argb.alpha);
154 return color.argb.alpha < MAX_TRANSPARENT;
155 }
156
IsColorFullTransparent(const SecCompColor & color)157 bool IsColorFullTransparent(const SecCompColor& color)
158 {
159 return color.argb.alpha == 0;
160 }
161 } // namespace SecurityComponent
162 } // namespace Security
163 } // namespace OHOS
164