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
38 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompTool"};
39 }
40
MaxValue(double a,double b,double c)41 static inline double MaxValue(double a, double b, double c)
42 {
43 return ((a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c));
44 }
45
MinValue(double a,double b,double c)46 static inline double MinValue(double a, double b, double c)
47 {
48 return ((a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c));
49 }
50
51 struct HsvColor {
52 double h;
53 double s;
54 double v;
55 };
56
RgbToHsv(uint8_t r,uint8_t g,uint8_t b)57 static HsvColor RgbToHsv(uint8_t r, uint8_t g, uint8_t b)
58 {
59 HsvColor hsv;
60 double red = static_cast<double>(r) / MAX_RGB_VALUE;
61 double green = static_cast<double>(g) / MAX_RGB_VALUE;
62 double blue = static_cast<double>(b) / MAX_RGB_VALUE;
63 double max = MaxValue(red, green, blue);
64 double min = MinValue(red, green, blue);
65 double delta = max - min;
66 if (max == min) {
67 hsv.h = ZERO_DOUBLE;
68 } else if (max == red) {
69 hsv.h = fmod((SIXTY_ANGLE * ((green - blue) / delta) + THREE_HUNDREDS_SIXTY_ANGLE),
70 THREE_HUNDREDS_SIXTY_ANGLE);
71 } else if (max == green) {
72 hsv.h = fmod((SIXTY_ANGLE * ((blue - red) / delta) + ONE_HUNDRED_TWEENTY_ANGLE), THREE_HUNDREDS_SIXTY_ANGLE);
73 } else if (max == blue) {
74 hsv.h = fmod((SIXTY_ANGLE * ((red - green) / delta) + TWO_HUNDREDS_FORTY_ANGLE), THREE_HUNDREDS_SIXTY_ANGLE);
75 }
76
77 if (max == 0) {
78 hsv.s = ZERO_DOUBLE;
79 } else {
80 hsv.s = delta / max;
81 }
82
83 hsv.v = max;
84 return hsv;
85 }
86
GetHsvDisX(const HsvColor & hsv,double r)87 static inline double GetHsvDisX(const HsvColor& hsv, double r)
88 {
89 return r * hsv.v * hsv.s * cos(hsv.h / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
90 }
91
GetHsvDisY(const HsvColor & hsv,double r)92 static inline double GetHsvDisY(const HsvColor& hsv, double r)
93 {
94 return r * hsv.v * hsv.s * sin(hsv.h / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
95 }
96
GetHsvDisZ(const HsvColor & hsv,double h)97 static inline double GetHsvDisZ(const HsvColor& hsv, double h)
98 {
99 return h * (1 - hsv.v);
100 }
101
HsvDistance(const HsvColor & hsv1,const HsvColor & hsv2)102 static double HsvDistance(const HsvColor& hsv1, const HsvColor& hsv2)
103 {
104 double rDef = DEFAULT_R;
105 double angle = THIRTY_ANGLE;
106 double h = rDef * cos(angle / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
107 double r = rDef * sin(angle / ONE_HUNDRED_EIGHTY_ANGLE * PI_CIRCLE);
108
109 double x1 = GetHsvDisX(hsv1, r);
110 double y1 = GetHsvDisY(hsv1, r);
111 double z1 = GetHsvDisZ(hsv1, h);
112
113 double x2 = GetHsvDisX(hsv2, r);
114 double y2 = GetHsvDisY(hsv2, r);
115 double z2 = GetHsvDisZ(hsv2, h);
116
117 double dx = x1 - x2;
118 double dy = y1 - y2;
119 double dz = z1 - z2;
120
121 return sqrt((dx * dx) + (dy * dy) + (dz * dz));
122 }
123
IsColorSimilar(const SecCompColor & color1,const SecCompColor & color2)124 bool IsColorSimilar(const SecCompColor& color1, const SecCompColor& color2)
125 {
126 HsvColor hsv1 = RgbToHsv(color1.argb.red, color1.argb.green, color1.argb.blue);
127 HsvColor hsv2 = RgbToHsv(color2.argb.red, color2.argb.green, color2.argb.blue);
128
129 double distance = HsvDistance(hsv1, hsv2);
130 SC_LOG_DEBUG(LABEL, "Compare color %{public}x %{public}x distance %{public}f",
131 color1.value, color2.value, distance);
132 return (distance < MIN_HSV_DISTANCE);
133 }
134
IsColorTransparent(const SecCompColor & color)135 bool IsColorTransparent(const SecCompColor& color)
136 {
137 SC_LOG_DEBUG(LABEL, "Color %{public}x alpha %{public}x", color.value, color.argb.alpha);
138 return color.argb.alpha < MAX_TRANSPARENT;
139 }
140 } // namespace SecurityComponent
141 } // namespace Security
142 } // namespace OHOS
143