1 /*
2 * Copyright (c) 2021-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 #include "skia_color_space.h"
17 #include "skia_data.h"
18 #include "skia_image.h"
19
20 #include "image/image.h"
21 #include "utils/log.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace Drawing {
SkiaColorSpace()26 SkiaColorSpace::SkiaColorSpace() noexcept : colorSpace_(nullptr) {}
27
InitWithSRGB()28 void SkiaColorSpace::InitWithSRGB()
29 {
30 colorSpace_ = SkColorSpace::MakeSRGB();
31 }
32
InitWithSRGBLinear()33 void SkiaColorSpace::InitWithSRGBLinear()
34 {
35 colorSpace_ = SkColorSpace::MakeSRGBLinear();
36 }
37
InitWithImage(const Image & image)38 void SkiaColorSpace::InitWithImage(const Image& image)
39 {
40 auto i = image.GetImpl<SkiaImage>();
41 if (i != nullptr) {
42 const sk_sp<SkImage> skiaImage = i->GetImage();
43 colorSpace_ = skiaImage->refColorSpace();
44 }
45 }
46
ConvertToSkCMSTransferFunction(const CMSTransferFuncType & func)47 static inline skcms_TransferFunction ConvertToSkCMSTransferFunction(const CMSTransferFuncType& func)
48 {
49 switch (func) {
50 case CMSTransferFuncType::SRGB:
51 return SkNamedTransferFn::kSRGB;
52 case CMSTransferFuncType::DOT2:
53 return SkNamedTransferFn::k2Dot2;
54 case CMSTransferFuncType::LINEAR:
55 return SkNamedTransferFn::kLinear;
56 case CMSTransferFuncType::REC2020:
57 return SkNamedTransferFn::kRec2020;
58 case CMSTransferFuncType::HLG:
59 return SkNamedTransferFn::kHLG;
60 default:
61 return SkNamedTransferFn::kSRGB;
62 }
63 }
64
ConvertToSkCMSMatrix3x3(const CMSMatrixType & matrix)65 static inline skcms_Matrix3x3 ConvertToSkCMSMatrix3x3(const CMSMatrixType& matrix)
66 {
67 switch (matrix) {
68 case CMSMatrixType::SRGB:
69 return SkNamedGamut::kSRGB;
70 case CMSMatrixType::ADOBE_RGB:
71 return SkNamedGamut::kAdobeRGB;
72 case CMSMatrixType::DCIP3:
73 return SkNamedGamut::kDisplayP3;
74 case CMSMatrixType::REC2020:
75 return SkNamedGamut::kRec2020;
76 case CMSMatrixType::XYZ:
77 return SkNamedGamut::kXYZ;
78 default:
79 return SkNamedGamut::kSRGB;
80 }
81 }
82
InitWithRGB(const CMSTransferFuncType & func,const CMSMatrixType & matrix)83 void SkiaColorSpace::InitWithRGB(const CMSTransferFuncType& func, const CMSMatrixType& matrix)
84 {
85 colorSpace_ = SkColorSpace::MakeRGB(ConvertToSkCMSTransferFunction(func), ConvertToSkCMSMatrix3x3(matrix));
86 }
87
InitWithCustomRGB(const CMSTransferFunction & func,const CMSMatrix3x3 & matrix)88 void SkiaColorSpace::InitWithCustomRGB(const CMSTransferFunction& func, const CMSMatrix3x3& matrix)
89 {
90 skcms_Matrix3x3 skMatrix3x3;
91 for (int i = 0; i < MATRIX3_SIZE; i++) {
92 for (int j = 0; j < MATRIX3_SIZE; j++) {
93 skMatrix3x3.vals[i][j] = matrix.vals[i][j];
94 }
95 }
96 skcms_TransferFunction skTransferFunc = { func.g, func.a, func.b, func.c, func.d, func.e, func.f };
97 colorSpace_ = SkColorSpace::MakeRGB(skTransferFunc, skMatrix3x3);
98 }
99
SetColorSpace(sk_sp<SkColorSpace> skColorSpace)100 void SkiaColorSpace::SetColorSpace(sk_sp<SkColorSpace> skColorSpace)
101 {
102 colorSpace_ = skColorSpace;
103 }
104
GetColorSpace() const105 sk_sp<SkColorSpace> SkiaColorSpace::GetColorSpace() const
106 {
107 return colorSpace_;
108 }
109
GetSkColorSpace() const110 sk_sp<SkColorSpace> SkiaColorSpace::GetSkColorSpace() const
111 {
112 return colorSpace_;
113 }
114
Serialize() const115 std::shared_ptr<Data> SkiaColorSpace::Serialize() const
116 {
117 if (colorSpace_ == nullptr) {
118 LOGD("SkiaColorSpace::Serialize, colorSpace_ is nullptr!");
119 return nullptr;
120 }
121
122 auto skData = colorSpace_->serialize();
123 std::shared_ptr<Data> data = std::make_shared<Data>();
124 auto dataImpl = data->GetImpl<SkiaData>();
125 if (dataImpl == nullptr) {
126 LOGD("SkiaColorSpace::Serialize, dataImpl is nullptr!");
127 return nullptr;
128 }
129 dataImpl->SetSkData(skData);
130 return data;
131 }
132
Deserialize(std::shared_ptr<Data> data)133 bool SkiaColorSpace::Deserialize(std::shared_ptr<Data> data)
134 {
135 if (data == nullptr) {
136 LOGD("SkiaColorSpace::Deserialize, data is invalid!");
137 return false;
138 }
139
140 colorSpace_ = SkColorSpace::Deserialize(data->GetData(), data->GetSize());
141 return true;
142 }
143
IsSRGB() const144 bool SkiaColorSpace::IsSRGB() const
145 {
146 if (colorSpace_ == nullptr) {
147 LOGD("SkiaColorSpace::IsSRGB, colorSpace_ is nullptr!");
148 return false;
149 }
150 return colorSpace_->isSRGB();
151 }
152
Equals(const std::shared_ptr<ColorSpace> & colorSpace) const153 bool SkiaColorSpace::Equals(const std::shared_ptr<ColorSpace>& colorSpace) const
154 {
155 sk_sp<SkColorSpace> skColorSpace = nullptr;
156 if (colorSpace != nullptr) {
157 auto skiaColorSpace = colorSpace->GetImpl<SkiaColorSpace>();
158 if (skiaColorSpace != nullptr) {
159 skColorSpace = skiaColorSpace->colorSpace_;
160 }
161 }
162 return SkColorSpace::Equals(colorSpace_.get(), skColorSpace.get());
163 }
164
ToXYZD50(bool & hasToXYZD50)165 CMSMatrix3x3 SkiaColorSpace::ToXYZD50(bool& hasToXYZD50)
166 {
167 CMSMatrix3x3 xyzGamut;
168 if (colorSpace_ == nullptr) {
169 hasToXYZD50 = false;
170 return xyzGamut;
171 }
172 skcms_ICCProfile encodedProfile;
173 colorSpace_->toProfile(&encodedProfile);
174 hasToXYZD50 = encodedProfile.has_toXYZD50;
175 if (!hasToXYZD50) {
176 LOGW("This profile's gamut can not be represented by a 3x3 tranform to XYZD50");
177 return xyzGamut;
178 }
179 skcms_Matrix3x3 skiaXYZGamut = encodedProfile.toXYZD50;
180 for (int i = 0; i < MATRIX3_SIZE; i++) {
181 for (int j = 0; j < MATRIX3_SIZE; j++) {
182 xyzGamut.vals[i][j] = skiaXYZGamut.vals[i][j];
183 }
184 }
185 return xyzGamut;
186 }
187 } // namespace Drawing
188 } // namespace Rosen
189 } // namespace OHOS