• 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 #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