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     }
59 }
60 
ConvertToSkCMSMatrix3x3(const CMSMatrixType & matrix)61 static inline skcms_Matrix3x3 ConvertToSkCMSMatrix3x3(const CMSMatrixType& matrix)
62 {
63     switch (matrix) {
64         case CMSMatrixType::SRGB:
65             return SkNamedGamut::kSRGB;
66         case CMSMatrixType::ADOBE_RGB:
67             return SkNamedGamut::kAdobeRGB;
68         case CMSMatrixType::DCIP3:
69             return SkNamedGamut::kDisplayP3;
70         case CMSMatrixType::REC2020:
71             return SkNamedGamut::kRec2020;
72         case CMSMatrixType::XYZ:
73             return SkNamedGamut::kXYZ;
74     }
75 }
76 
InitWithRGB(const CMSTransferFuncType & func,const CMSMatrixType & matrix)77 void SkiaColorSpace::InitWithRGB(const CMSTransferFuncType& func, const CMSMatrixType& matrix)
78 {
79     colorSpace_ = SkColorSpace::MakeRGB(ConvertToSkCMSTransferFunction(func), ConvertToSkCMSMatrix3x3(matrix));
80 }
81 
InitWithCustomRGB(const CMSTransferFunction & func,const CMSMatrix3x3 & matrix)82 void SkiaColorSpace::InitWithCustomRGB(const CMSTransferFunction& func, const CMSMatrix3x3& matrix)
83 {
84     skcms_Matrix3x3 skMatrix3x3;
85     for (int i = 0; i < MATRIX3_SIZE; i++) {
86         for (int j = 0; j < MATRIX3_SIZE; j++) {
87             skMatrix3x3.vals[i][j] = matrix.vals[i][j];
88         }
89     }
90     skcms_TransferFunction skTransferFunc = { func.g, func.a, func.b, func.d, func.e, func.f };
91     colorSpace_ = SkColorSpace::MakeRGB(skTransferFunc, skMatrix3x3);
92 }
93 
SetColorSpace(sk_sp<SkColorSpace> skColorSpace)94 void SkiaColorSpace::SetColorSpace(sk_sp<SkColorSpace> skColorSpace)
95 {
96     colorSpace_ = skColorSpace;
97 }
98 
GetColorSpace() const99 sk_sp<SkColorSpace> SkiaColorSpace::GetColorSpace() const
100 {
101     return colorSpace_;
102 }
103 
GetSkColorSpace() const104 sk_sp<SkColorSpace> SkiaColorSpace::GetSkColorSpace() const
105 {
106     return colorSpace_;
107 }
108 
Serialize() const109 std::shared_ptr<Data> SkiaColorSpace::Serialize() const
110 {
111     if (colorSpace_ == nullptr) {
112         LOGD("SkiaColorSpace::Serialize, colorSpace_ is nullptr!");
113         return nullptr;
114     }
115 
116     auto skData = colorSpace_->serialize();
117     std::shared_ptr<Data> data = std::make_shared<Data>();
118     data->GetImpl<SkiaData>()->SetSkData(skData);
119     return data;
120 }
121 
Deserialize(std::shared_ptr<Data> data)122 bool SkiaColorSpace::Deserialize(std::shared_ptr<Data> data)
123 {
124     if (data == nullptr) {
125         LOGD("SkiaColorSpace::Deserialize, data is invalid!");
126         return false;
127     }
128 
129     colorSpace_ = SkColorSpace::Deserialize(data->GetData(), data->GetSize());
130     return true;
131 }
132 
IsSRGB() const133 bool SkiaColorSpace::IsSRGB() const
134 {
135     if (colorSpace_ == nullptr) {
136         LOGD("SkiaColorSpace::IsSRGB, colorSpace_ is nullptr!");
137         return false;
138     }
139     return colorSpace_->isSRGB();
140 }
141 
Equals(const std::shared_ptr<ColorSpace> & colorSpace) const142 bool SkiaColorSpace::Equals(const std::shared_ptr<ColorSpace>& colorSpace) const
143 {
144     sk_sp<SkColorSpace> skColorSpace = nullptr;
145     if (colorSpace != nullptr) {
146         auto skiaColorSpace = colorSpace->GetImpl<SkiaColorSpace>();
147         if (skiaColorSpace != nullptr) {
148             skColorSpace = skiaColorSpace->colorSpace_;
149         }
150     }
151     return SkColorSpace::Equals(colorSpace_.get(), skColorSpace.get());
152 }
153 
154 } // namespace Drawing
155 } // namespace Rosen
156 } // namespace OHOS