• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #ifndef COLORSPACE
17 #define COLORSPACE
18 
19 #include <array>
20 #include <cfloat>
21 #include <cmath>
22 #include <map>
23 #include <utility>
24 
25 #include "include/core/SkColorSpace.h"
26 #ifdef USE_M133_SKIA
27 #include "modules/skcms/skcms.h"
28 #else
29 #include "include/third_party/skcms/skcms.h"
30 #endif
31 
32 namespace OHOS {
33 namespace ColorManager {
34 #define DIMES_3 3
35 #define DIMES_2 2
36 
37 using Vector3 = std::array<float, DIMES_3>;
38 using Matrix3x3 = std::array<Vector3, DIMES_3>;
39 static constexpr float COLOR_EPSILON = 0.0018f; // 1/255/2 = 0.00196
40 static const std::array<float, DIMES_2> ILLUMINANT_D50_XY = {0.34567f, 0.35850f};
41 static const Vector3 ILLUMINANT_D50_XYZ = {0.964212f, 1.0f, 0.825188f};
42 static const Matrix3x3 BRADFORD = {{
43     {0.8951f, 0.2664f, -0.1614f},
44     {-0.7502f, 1.7135f, 0.0367f},
45     {0.0389f, -0.0685f, 1.0296f}}};
46 static const Matrix3x3 BRADFORD_INV = {{
47     {0.9869929f, -0.1470543f, 0.1599627f},
48     {0.4323053f,  0.5183603f, 0.0492912f},
49     {-0.0085287f, 0.0400428f, 0.9684867f},
50 }};
51 
52 enum ColorSpaceName : uint32_t {
53     NONE = 0,
54     ADOBE_RGB = 1,
55     DCI_P3 = 2,
56     DISPLAY_P3 = 3,
57     SRGB = 4,
58     BT709 = 6,
59     BT601_EBU = 7,
60     BT601_SMPTE_C = 8,
61     BT2020_HLG = 9,
62     BT2020_PQ = 10,
63     P3_HLG = 11,
64     P3_PQ = 12,
65     ADOBE_RGB_LIMIT = 13,
66     DISPLAY_P3_LIMIT = 14,
67     SRGB_LIMIT = 15,
68     BT709_LIMIT = 16,
69     BT601_EBU_LIMIT = 17,
70     BT601_SMPTE_C_LIMIT = 18,
71     BT2020_HLG_LIMIT = 19,
72     BT2020_PQ_LIMIT = 20,
73     P3_HLG_LIMIT = 21,
74     P3_PQ_LIMIT = 22,
75     LINEAR_P3 = 23,
76     LINEAR_SRGB = 24,
77     LINEAR_BT709 = LINEAR_SRGB,
78     LINEAR_BT2020 = 25,
79     DISPLAY_SRGB = SRGB,
80     DISPLAY_P3_SRGB = DISPLAY_P3,
81     DISPLAY_P3_HLG = P3_HLG,
82     DISPLAY_P3_PQ = P3_PQ,
83     DISPLAY_BT2020_SRGB = 26,
84     DISPLAY_BT2020_HLG = BT2020_HLG,
85     DISPLAY_BT2020_PQ = BT2020_PQ,
86     BT2020 = 27,
87     NTSC_1953 = 28,
88     PRO_PHOTO_RGB = 29,
89     ACES = 30,
90     ACESCG = 31,
91     CIE_LAB = 32,
92     CIE_XYZ = 33,
93     EXTENDED_SRGB = 34,
94     LINEAR_EXTENDED_SRGB = 35,
95     SMPTE_C = 36,
96     CUSTOM = 5,
97     H_LOG = 37,
98 };
99 
100 enum GamutMappingMode : uint32_t {
101     GAMUT_MAP_CONSTANT = 0,
102     GAMUT_MAP_EXPENSION,
103     GAMUT_MAP_HDR_CONSTANT,
104     GAMUT_MAP_HDR_EXPENSION,
105 };
106 
107 struct ColorSpacePrimaries {
108     float rX;
109     float rY;
110     float gX;
111     float gY;
112     float bX;
113     float bY;
114     float wX;
115     float wY;
116 };
117 
118 struct TransferFunc {
119     float g;
120     float a;
121     float b;
122     float c;
123     float d;
124     float e;
125     float f;
126 };
127 
128 Matrix3x3 operator*(const Matrix3x3& a, const Matrix3x3& b);
129 
130 Vector3 operator*(const Vector3& x, const Matrix3x3& a);
131 
132 Vector3 operator*(const Matrix3x3& a, const Vector3& x);
133 
134 Matrix3x3 operator/(const Vector3& a, const Vector3& b);
135 
136 Matrix3x3 Invert(const Matrix3x3& src);
137 
XYZ(const Vector3 & xyY)138 inline Vector3 XYZ(const Vector3& xyY)
139 {
140     return Vector3 {(xyY[0] * xyY[2]) / xyY[1], xyY[2],
141         ((1 - xyY[0] - xyY[1]) * xyY[2]) / xyY[1]};
142 }
143 
FloatEqual(const float src,const float dst)144 inline bool FloatEqual(const float src, const float dst)
145 {
146     return fabs(src - dst) < COLOR_EPSILON;
147 }
148 
ComputeWhitePoint(Matrix3x3 & toXYZ)149 inline std::array<float, DIMES_2> ComputeWhitePoint(Matrix3x3 &toXYZ)
150 {
151     Vector3 w = toXYZ * Vector3 {1.0f};
152     float sumW = w[0] + w[1] + w[2];
153     return {{w[0] / sumW, w[1] / sumW}};
154 }
155 
SkToXYZToMatrix3(const skcms_Matrix3x3 & skToXYZ)156 inline Matrix3x3 SkToXYZToMatrix3(const skcms_Matrix3x3 &skToXYZ)
157 {
158     return {{{skToXYZ.vals[0][0], skToXYZ.vals[0][1], skToXYZ.vals[0][2]},
159         {skToXYZ.vals[1][0], skToXYZ.vals[1][1], skToXYZ.vals[1][2]},
160         {skToXYZ.vals[2][0], skToXYZ.vals[2][1], skToXYZ.vals[2][2]}}};
161 }
162 
163 // Compute a toXYZD50 matrix from a given rgb and white point
164 Matrix3x3 ComputeXYZD50(const ColorSpacePrimaries& primaries);
165 
166 // Convert toXYZ to toXYZD50 matrix with its white point
167 Matrix3x3 DXToD50(const Matrix3x3 &toXYZ, const std::array<float, DIMES_2> &wp);
168 
169 class ColorSpace {
170 public:
171     ColorSpace(ColorSpaceName name);
172 
173     ColorSpace(const ColorSpacePrimaries &primaries, const TransferFunc &transferFunc);
174 
175     ColorSpace(const ColorSpacePrimaries &primaries, float gamma);
176 
177     ColorSpace(const Matrix3x3& toXYZ, const std::array<float, 2> &whitePoint, const TransferFunc& transferFunc);
178 
179     ColorSpace(const Matrix3x3& toXYZ, const std::array<float, 2>& whitePoint, float gamma);
180 
181     // convert SKColorSpace to OHOS ColorSpce
182     ColorSpace(const sk_sp<SkColorSpace> src, ColorSpaceName name = ColorSpaceName::CUSTOM);
183 
184     ColorSpace(const skcms_ICCProfile& srcIcc, ColorSpaceName name = ColorSpaceName::CUSTOM);
185 
GetColorSpaceName()186     ColorSpaceName GetColorSpaceName() const
187     {
188         return colorSpaceName;
189     }
190 
GetRGBToXYZ()191     Matrix3x3 GetRGBToXYZ() const
192     {
193         return toXYZ;
194     }
195 
GetXYZToRGB()196     Matrix3x3 GetXYZToRGB() const
197     {
198         auto toRGB = Invert(toXYZ);
199         return toRGB;
200     }
201 
GetWhitePoint()202     std::array<float, DIMES_2> GetWhitePoint() const
203     {
204         return whitePoint;
205     }
206 
GetGamma()207     float GetGamma() const
208     {
209         return transferFunc.g;
210     }
211 
GetTransferFunction()212     TransferFunc GetTransferFunction() const
213     {
214         return transferFunc;
215     }
216 
217     Vector3 ToLinear(Vector3 color) const;
218     Vector3 ToNonLinear(Vector3 color) const;
219 
220     // convert OHOS ColorSpce to SKColorSpace
221     sk_sp<SkColorSpace> ToSkColorSpace() const;
222 
223     float clampMin = 0.0f;
224     float clampMax = 1.0f;
225 
226 private:
227     skcms_Matrix3x3 ToSkiaXYZ() const;
228 
229     ColorSpaceName colorSpaceName = ColorSpaceName::SRGB;
230     Matrix3x3 toXYZ;
231     std::array<float, DIMES_2> whitePoint;
232     TransferFunc transferFunc = {};
233 };
234 } // namespace ColorSpace
235 } // namespace OHOS
236 #endif  // COLORSPACE
237