1 /*
2  * Copyright (C) 2021 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 #ifndef FRAMEWORKS_INNERKITSIMPL_CONVERTER_INCLUDE_MATRIX_H
17 #define FRAMEWORKS_INNERKITSIMPL_CONVERTER_INCLUDE_MATRIX_H
18 
19 #include <cmath>
20 #include "image_type.h"
21 
22 namespace OHOS {
23 namespace Media {
24 struct Point {
25     float x = 0.0f;
26     float y = 0.0f;
27 };
28 
29 static constexpr int32_t IMAGE_SCALEX = 0;
30 static constexpr int32_t IMAGE_SKEWX = 1;
31 static constexpr int32_t IMAGE_TRANSX = 2;
32 static constexpr int32_t IMAGE_SKEWY = 3;
33 static constexpr int32_t IMAGE_SCALEY = 4;
34 static constexpr int32_t IMAGE_TRANSY = 5;
35 static constexpr int32_t IMAGE_PERSP0 = 6;
36 static constexpr int32_t IMAGE_PERSP1 = 7;
37 static constexpr int32_t IMAGE_PERSP2 = 8;
38 static constexpr int32_t MATIRX_ITEM_NUM = 9;
39 
40 static constexpr uint32_t IDENTITY_TYPE = 0;
41 static constexpr uint32_t TRANSLATE_TYPE = 0x01;
42 static constexpr uint32_t SCALE_TYPE = 0x02;
43 static constexpr uint32_t ROTATEORSKEW_TYPE = 0x04;
44 static constexpr uint32_t PERSPECTIVE_TYPE = 0x08;
45 
46 static constexpr float FLOAT_PI = 3.14159265f;
47 static constexpr float FLOAT_NEAR_ZERO = (1.0f / (1 << 12));
48 static constexpr float RADIAN_FACTOR = 180.0f;
49 static constexpr uint32_t CALCPROC_FACTOR = 0x07;
50 static constexpr uint32_t OPERTYPE_MASK = 0xF;
51 static constexpr float MATRIX_EPSILON = 1e-6;
52 
53 // Degrees to Radians
DegreesToRadians(const float degrees)54 static inline float DegreesToRadians(const float degrees)
55 {
56     return degrees * (FLOAT_PI / RADIAN_FACTOR);
57 }
58 
59 // Radians to Degrees
RadiansToDegrees(const float radians)60 static inline float RadiansToDegrees(const float radians)
61 {
62     return radians * (RADIAN_FACTOR / FLOAT_PI);
63 }
64 
ValueNearToZero(const float radians,bool isSin)65 static inline float ValueNearToZero(const float radians, bool isSin)
66 {
67     float value = (isSin ? sinf(radians) : cosf(radians));
68     return (fabsf(value) <= FLOAT_NEAR_ZERO) ? 0.0f : value;
69 }
70 
MulAddMul(const float a,const float b,const float c,const float d)71 static inline double MulAddMul(const float a, const float b, const float c, const float d)
72 {
73     return a * b + c * d;
74 }
75 
MulSubMul(const float a,const float b,const float c,const float d)76 static inline double MulSubMul(const float a, const float b, const float c, const float d)
77 {
78     return a * b - c * d;
79 }
80 
FDivide(const float number,const float denom)81 static inline float FDivide(const float number, const float denom)
82 {
83     if (std::fabs(denom - 0) < MATRIX_EPSILON) {
84         return 0.0f;
85     }
86     return number / denom;
87 }
88 
89 class Matrix {
90 public:
91     enum OperType {
92         IDENTITY = IDENTITY_TYPE,
93         TRANSLATE = TRANSLATE_TYPE,
94         SCALE = SCALE_TYPE,
95         ROTATEORSKEW = ROTATEORSKEW_TYPE,
96         PERSPECTIVE = PERSPECTIVE_TYPE,
97     };
98 
99     using CalcXYProc = void (*)(const Matrix &m, const float x, const float y, Point &result);
100 
101     /** The default is the identity matrix
102      * | 1  0  0 |
103      * | 0  1  0 |
104      * | 0  0  1 |
105      */
Matrix()106     constexpr Matrix() : Matrix(1, 0, 0, 0, 1, 0, 0, 0, 1, IDENTITY) {}
107 
Matrix(float sx,float kx,float tx,float ky,float sy,float ty,float p0,float p1,float p2,uint32_t operType)108     constexpr Matrix(float sx, float kx, float tx, float ky, float sy, float ty, float p0, float p1, float p2,
109                      uint32_t operType)
110         : fMat_ { sx, kx, tx, ky, sy, ty, p0, p1, p2 }, operType_(operType) {}
111 
112     ~Matrix() = default;
113 
114     static const CalcXYProc gCalcXYProcs[];
115 
IsIdentity()116     bool IsIdentity() const
117     {
118         return GetOperType() == 0;
119     }
120 
121     Matrix &SetTranslate(const float tx, const float ty);
122 
123     Matrix &SetScale(const float sx, const float sy);
124 
125     Matrix &SetRotate(const float degrees, const float px = 0.0, const float py = 0.0);
126 
127     Matrix &SetSinCos(const float sinValue, const float cosValue, const float px, const float py);
128 
129     Matrix &SetConcat(const Matrix &m);
130 
131     Matrix &Reset();
132 
133     OperType GetOperType() const;
134 
135     void SetTranslateAndScale(const float tx, const float ty, const float sx, const float sy);
136 
137     static void IdentityXY(const Matrix &m, const float sx, const float sy, Point &pt);
138 
139     static void ScaleXY(const Matrix &m, const float sx, const float sy, Point &pt);
140 
141     static void TransXY(const Matrix &m, const float tx, const float sy, Point &pt);
142 
143     static void RotXY(const Matrix &m, const float rx, const float ry, Point &pt);
144 
GetXYProc(const OperType operType)145     static CalcXYProc GetXYProc(const OperType operType)
146     {
147         return gCalcXYProcs[static_cast<uint8_t>(operType) & CALCPROC_FACTOR];
148     }
149 
150     bool Invert(Matrix &invMatrix);
151 
152     bool InvertForRotate(Matrix &invMatrix);
153 
GetScaleX()154     float GetScaleX() const
155     {
156         return fMat_[IMAGE_SCALEX];
157     }
158 
GetScaleY()159     float GetScaleY() const
160     {
161         return fMat_[IMAGE_SCALEY];
162     }
163 
GetTransX()164     float GetTransX() const
165     {
166         return fMat_[IMAGE_TRANSX];
167     }
168 
GetTranY()169     float GetTranY() const
170     {
171         return fMat_[IMAGE_TRANSY];
172     }
173 
GetSkewX()174     float GetSkewX() const
175     {
176         return fMat_[IMAGE_SKEWX];
177     }
178 
GetSkewY()179     float GetSkewY() const
180     {
181         return fMat_[IMAGE_SKEWY];
182     }
183 
184     void Print();
185 
186 private:
187     /** The fMat_ elements
188      *  | scalex  skewx  transx |
189      *  | skewy   scaley transy |
190      *  | persp0  persp1 persp2 |
191      */
192     float fMat_[MATIRX_ITEM_NUM];
193     uint32_t operType_;
194 };
195 } // namespace Media
196 } // namespace OHOS
197 #endif // FRAMEWORKS_INNERKITSIMPL_CONVERTER_INCLUDE_MATRIX_H
198