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 OHOS_JS_COLOR_SPACE_UTILS_H
17 #define OHOS_JS_COLOR_SPACE_UTILS_H
18
19 #include <map>
20 #include <string>
21 #include <hilog/log.h>
22
23 #include "color_space.h"
24 #include "color_manager_common.h"
25 #include "napi/native_api.h"
26 #include "napi/native_node_api.h"
27
28 namespace OHOS {
29 namespace ColorManager {
30
31 #undef LOG_DOMAIN
32 #define LOG_DOMAIN 0xD001400
33
34 #undef LOG_TAG
35 #define LOG_TAG "JsColorSpace"
36
37 #define CMLOGE(fmt, args...) HILOG_ERROR(LOG_CORE, fmt, ##args)
38 #define CMLOGI(fmt, args...) HILOG_INFO(LOG_CORE, fmt, ##args)
39
40 enum class ApiColorSpaceType : uint32_t {
41 UNKNOWN = 0,
42 ADOBE_RGB_1998 = 1,
43 DCI_P3 = 2,
44 DISPLAY_P3 = 3,
45 SRGB = 4,
46 BT709 = 6,
47 BT601_EBU = 7,
48 BT601_SMPTE_C = 8,
49 BT2020_HLG = 9,
50 BT2020_PQ = 10,
51 P3_HLG = 11,
52 P3_PQ = 12,
53 ADOBE_RGB_1998_LIMIT = 13,
54 DISPLAY_P3_LIMIT = 14,
55 SRGB_LIMIT = 15,
56 BT709_LIMIT = 16,
57 BT601_EBU_LIMIT = 17,
58 BT601_SMPTE_C_LIMIT = 18,
59 BT2020_HLG_LIMIT = 19,
60 BT2020_PQ_LIMIT = 20,
61 P3_HLG_LIMIT = 21,
62 P3_PQ_LIMIT = 22,
63 LINEAR_P3 = 23,
64 LINEAR_SRGB = 24,
65 LINEAR_BT709 = LINEAR_SRGB,
66 LINEAR_BT2020 = 25,
67 DISPLAY_SRGB = SRGB,
68 DISPLAY_P3_SRGB = DISPLAY_P3,
69 DISPLAY_P3_HLG = P3_HLG,
70 DISPLAY_P3_PQ = P3_PQ,
71 CUSTOM = 5,
72 H_LOG = 26,
73 DISPLAY_BT2020_SRGB = 27,
74 TYPE_END = 28
75 };
76
77 const std::map<ColorSpaceName, ApiColorSpaceType> NATIVE_TO_JS_COLOR_SPACE_TYPE_MAP {
78 { ColorSpaceName::NONE, ApiColorSpaceType::UNKNOWN },
79 { ColorSpaceName::ADOBE_RGB, ApiColorSpaceType::ADOBE_RGB_1998 },
80 { ColorSpaceName::DCI_P3, ApiColorSpaceType::DCI_P3 },
81 { ColorSpaceName::DISPLAY_P3, ApiColorSpaceType::DISPLAY_P3 },
82 { ColorSpaceName::SRGB, ApiColorSpaceType::SRGB },
83 { ColorSpaceName::BT709, ApiColorSpaceType::BT709 },
84 { ColorSpaceName::BT601_EBU, ApiColorSpaceType::BT601_EBU },
85 { ColorSpaceName::BT601_SMPTE_C, ApiColorSpaceType::BT601_SMPTE_C },
86 { ColorSpaceName::BT2020_HLG, ApiColorSpaceType::BT2020_HLG },
87 { ColorSpaceName::BT2020_PQ, ApiColorSpaceType::BT2020_PQ },
88 { ColorSpaceName::P3_HLG, ApiColorSpaceType::P3_HLG },
89 { ColorSpaceName::P3_PQ, ApiColorSpaceType::P3_PQ },
90 { ColorSpaceName::ADOBE_RGB_LIMIT, ApiColorSpaceType::ADOBE_RGB_1998_LIMIT },
91 { ColorSpaceName::DISPLAY_P3_LIMIT, ApiColorSpaceType::DISPLAY_P3_LIMIT },
92 { ColorSpaceName::SRGB_LIMIT, ApiColorSpaceType::SRGB_LIMIT },
93 { ColorSpaceName::BT709_LIMIT, ApiColorSpaceType::BT709_LIMIT },
94 { ColorSpaceName::BT601_EBU_LIMIT, ApiColorSpaceType::BT601_EBU_LIMIT },
95 { ColorSpaceName::BT601_SMPTE_C_LIMIT, ApiColorSpaceType::BT601_SMPTE_C_LIMIT },
96 { ColorSpaceName::BT2020_HLG_LIMIT, ApiColorSpaceType::BT2020_HLG_LIMIT },
97 { ColorSpaceName::BT2020_PQ_LIMIT, ApiColorSpaceType::BT2020_PQ_LIMIT },
98 { ColorSpaceName::P3_HLG_LIMIT, ApiColorSpaceType::P3_HLG_LIMIT },
99 { ColorSpaceName::P3_PQ_LIMIT, ApiColorSpaceType::P3_PQ_LIMIT },
100 { ColorSpaceName::LINEAR_P3, ApiColorSpaceType::LINEAR_P3 },
101 { ColorSpaceName::LINEAR_SRGB, ApiColorSpaceType::LINEAR_SRGB },
102 { ColorSpaceName::LINEAR_BT709, ApiColorSpaceType::LINEAR_BT709 },
103 { ColorSpaceName::LINEAR_BT2020, ApiColorSpaceType::LINEAR_BT2020 },
104 { ColorSpaceName::DISPLAY_SRGB, ApiColorSpaceType::DISPLAY_SRGB },
105 { ColorSpaceName::DISPLAY_P3_SRGB, ApiColorSpaceType::DISPLAY_P3_SRGB },
106 { ColorSpaceName::DISPLAY_P3_HLG, ApiColorSpaceType::DISPLAY_P3_HLG },
107 { ColorSpaceName::DISPLAY_P3_PQ, ApiColorSpaceType::DISPLAY_P3_PQ },
108 { ColorSpaceName::CUSTOM, ApiColorSpaceType::CUSTOM },
109 { ColorSpaceName::H_LOG, ApiColorSpaceType::H_LOG },
110 { ColorSpaceName::DISPLAY_BT2020_SRGB, ApiColorSpaceType::DISPLAY_BT2020_SRGB },
111 };
112
113 const std::map<ApiColorSpaceType, ColorSpaceName> JS_TO_NATIVE_COLOR_SPACE_NAME_MAP {
114 { ApiColorSpaceType::UNKNOWN, ColorSpaceName::NONE },
115 { ApiColorSpaceType::ADOBE_RGB_1998, ColorSpaceName::ADOBE_RGB },
116 { ApiColorSpaceType::DCI_P3, ColorSpaceName::DCI_P3 },
117 { ApiColorSpaceType::DISPLAY_P3, ColorSpaceName::DISPLAY_P3 },
118 { ApiColorSpaceType::SRGB, ColorSpaceName::SRGB },
119 { ApiColorSpaceType::BT709, ColorSpaceName::BT709 },
120 { ApiColorSpaceType::BT601_EBU, ColorSpaceName::BT601_EBU },
121 { ApiColorSpaceType::BT601_SMPTE_C, ColorSpaceName::BT601_SMPTE_C },
122 { ApiColorSpaceType::BT2020_HLG, ColorSpaceName::BT2020_HLG },
123 { ApiColorSpaceType::BT2020_PQ, ColorSpaceName::BT2020_PQ },
124 { ApiColorSpaceType::P3_HLG, ColorSpaceName::P3_HLG },
125 { ApiColorSpaceType::P3_PQ, ColorSpaceName::P3_PQ },
126 { ApiColorSpaceType::ADOBE_RGB_1998_LIMIT, ColorSpaceName::ADOBE_RGB_LIMIT },
127 { ApiColorSpaceType::DISPLAY_P3_LIMIT, ColorSpaceName::DISPLAY_P3_LIMIT },
128 { ApiColorSpaceType::SRGB_LIMIT, ColorSpaceName::SRGB_LIMIT },
129 { ApiColorSpaceType::BT709_LIMIT, ColorSpaceName::BT709_LIMIT },
130 { ApiColorSpaceType::BT601_EBU_LIMIT, ColorSpaceName::BT601_EBU_LIMIT },
131 { ApiColorSpaceType::BT601_SMPTE_C_LIMIT, ColorSpaceName::BT601_SMPTE_C_LIMIT },
132 { ApiColorSpaceType::BT2020_HLG_LIMIT, ColorSpaceName::BT2020_HLG_LIMIT },
133 { ApiColorSpaceType::BT2020_PQ_LIMIT, ColorSpaceName::BT2020_PQ_LIMIT },
134 { ApiColorSpaceType::P3_HLG_LIMIT, ColorSpaceName::P3_HLG_LIMIT },
135 { ApiColorSpaceType::P3_PQ_LIMIT, ColorSpaceName::P3_PQ_LIMIT },
136 { ApiColorSpaceType::LINEAR_P3, ColorSpaceName::LINEAR_P3 },
137 { ApiColorSpaceType::LINEAR_SRGB, ColorSpaceName::LINEAR_SRGB },
138 { ApiColorSpaceType::LINEAR_BT709, ColorSpaceName::LINEAR_BT709 },
139 { ApiColorSpaceType::LINEAR_BT2020, ColorSpaceName::LINEAR_BT2020 },
140 { ApiColorSpaceType::DISPLAY_SRGB, ColorSpaceName::DISPLAY_SRGB },
141 { ApiColorSpaceType::DISPLAY_P3_SRGB, ColorSpaceName::DISPLAY_P3_SRGB },
142 { ApiColorSpaceType::DISPLAY_P3_HLG, ColorSpaceName::DISPLAY_P3_HLG },
143 { ApiColorSpaceType::DISPLAY_P3_PQ, ColorSpaceName::DISPLAY_P3_PQ },
144 { ApiColorSpaceType::CUSTOM, ColorSpaceName::CUSTOM },
145 { ApiColorSpaceType::H_LOG, ColorSpaceName::H_LOG },
146 { ApiColorSpaceType::DISPLAY_BT2020_SRGB, ColorSpaceName::DISPLAY_BT2020_SRGB },
147 };
148
149 const std::map<std::string, ApiColorSpaceType> STRING_TO_JS_MAP = {
150 { "UNKNOWN", ApiColorSpaceType::UNKNOWN },
151 { "ADOBE_RGB_1998", ApiColorSpaceType::ADOBE_RGB_1998 },
152 { "DCI_P3", ApiColorSpaceType::DCI_P3 },
153 { "DISPLAY_P3", ApiColorSpaceType::DISPLAY_P3 },
154 { "SRGB", ApiColorSpaceType::SRGB },
155 { "BT709", ApiColorSpaceType::BT709 },
156 { "BT601_EBU", ApiColorSpaceType::BT601_EBU },
157 { "BT601_SMPTE_C", ApiColorSpaceType::BT601_SMPTE_C },
158 { "BT2020_HLG", ApiColorSpaceType::BT2020_HLG },
159 { "BT2020_PQ", ApiColorSpaceType::BT2020_PQ },
160 { "P3_HLG", ApiColorSpaceType::P3_HLG },
161 { "P3_PQ", ApiColorSpaceType::P3_PQ },
162 { "ADOBE_RGB_1998_LIMIT", ApiColorSpaceType::ADOBE_RGB_1998_LIMIT },
163 { "DISPLAY_P3_LIMIT", ApiColorSpaceType::DISPLAY_P3_LIMIT },
164 { "SRGB_LIMIT", ApiColorSpaceType::SRGB_LIMIT },
165 { "BT709_LIMIT", ApiColorSpaceType::BT709_LIMIT },
166 { "BT601_EBU_LIMIT", ApiColorSpaceType::BT601_EBU_LIMIT },
167 { "BT601_SMPTE_C_LIMIT", ApiColorSpaceType::BT601_SMPTE_C_LIMIT },
168 { "BT2020_HLG_LIMIT", ApiColorSpaceType::BT2020_HLG_LIMIT },
169 { "BT2020_PQ_LIMIT", ApiColorSpaceType::BT2020_PQ_LIMIT },
170 { "P3_HLG_LIMIT", ApiColorSpaceType::P3_HLG_LIMIT },
171 { "P3_PQ_LIMIT", ApiColorSpaceType::P3_PQ_LIMIT },
172 { "LINEAR_P3", ApiColorSpaceType::LINEAR_P3 },
173 { "LINEAR_SRGB", ApiColorSpaceType::LINEAR_SRGB },
174 { "LINEAR_BT709", ApiColorSpaceType::LINEAR_BT709 },
175 { "LINEAR_BT2020", ApiColorSpaceType::LINEAR_BT2020 },
176 { "DISPLAY_SRGB", ApiColorSpaceType::DISPLAY_SRGB },
177 { "DISPLAY_P3_SRGB", ApiColorSpaceType::DISPLAY_P3_SRGB },
178 { "DISPLAY_P3_HLG", ApiColorSpaceType::DISPLAY_P3_HLG },
179 { "DISPLAY_P3_PQ", ApiColorSpaceType::DISPLAY_P3_PQ },
180 { "CUSTOM", ApiColorSpaceType::CUSTOM },
181 { "H_LOG", ApiColorSpaceType::H_LOG },
182 { "DISPLAY_BT2020_SRGB", ApiColorSpaceType::DISPLAY_BT2020_SRGB },
183 };
184
185 template<class T>
186 T* CheckParamsAndGetThis(const napi_env env, napi_callback_info info, const char* name = nullptr)
187 {
188 if (env == nullptr || info == nullptr) {
189 return nullptr;
190 }
191 napi_value object = nullptr;
192 napi_value propertyNameValue = nullptr;
193 napi_value pointerValue = nullptr;
194 NAPI_CALL_DEFAULT(napi_get_cb_info(env, info, nullptr, nullptr, &object, nullptr));
195 if (object != nullptr && name != nullptr) {
196 NAPI_CALL_DEFAULT(napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &propertyNameValue));
197 }
198 napi_value& resObject = propertyNameValue ? propertyNameValue : object;
199 if (resObject) {
200 return napi_unwrap(env, resObject, (void **)(&pointerValue)) == napi_ok ?
201 reinterpret_cast<T*>(pointerValue) : nullptr;
202 }
203 return nullptr;
204 }
205
206 template<class T>
207 T* CheckSendableParamsAndGetThis(const napi_env env, napi_callback_info info, const char* name = nullptr)
208 {
209 if (env == nullptr || info == nullptr) {
210 return nullptr;
211 }
212 napi_value object = nullptr;
213 napi_value propertyNameValue = nullptr;
214 napi_value pointerValue = nullptr;
215 NAPI_CALL_DEFAULT(napi_get_cb_info(env, info, nullptr, nullptr, &object, nullptr));
216 if (object != nullptr && name != nullptr) {
217 NAPI_CALL_DEFAULT(napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &propertyNameValue));
218 }
219 napi_value& resObject = propertyNameValue ? propertyNameValue : object;
220 if (resObject) {
221 return napi_unwrap_sendable(env, resObject, (void **)(&pointerValue)) == napi_ok ?
222 reinterpret_cast<T*>(pointerValue) : nullptr;
223 }
224 return nullptr;
225 }
226
227 template<typename T, size_t N>
ArraySize(T (&)[N])228 inline constexpr size_t ArraySize(T (&)[N]) noexcept
229 {
230 return N;
231 }
232
CreateJsUndefined(napi_env env)233 inline napi_value CreateJsUndefined(napi_env env)
234 {
235 napi_value result = nullptr;
236 NAPI_CALL_DEFAULT(napi_get_undefined(env, &result));
237 return result;
238 }
239
CreateJsNull(napi_env env)240 inline napi_value CreateJsNull(napi_env env)
241 {
242 napi_value result = nullptr;
243 NAPI_CALL_DEFAULT(napi_get_null(env, &result));
244 return result;
245 }
246
CreateJsNumber(napi_env env,int32_t value)247 inline napi_value CreateJsNumber(napi_env env, int32_t value)
248 {
249 napi_value result = nullptr;
250 NAPI_CALL_DEFAULT(napi_create_int32(env, value, &result));
251 return result;
252 }
253
CreateJsNumber(napi_env env,uint32_t value)254 inline napi_value CreateJsNumber(napi_env env, uint32_t value)
255 {
256 napi_value result = nullptr;
257 NAPI_CALL_DEFAULT(napi_create_uint32(env, value, &result));
258 return result;
259 }
260
CreateJsNumber(napi_env env,int64_t value)261 inline napi_value CreateJsNumber(napi_env env, int64_t value)
262 {
263 napi_value result = nullptr;
264 NAPI_CALL_DEFAULT(napi_create_int64(env, value, &result));
265 return result;
266 }
267
CreateJsNumber(napi_env env,double value)268 inline napi_value CreateJsNumber(napi_env env, double value)
269 {
270 napi_value result = nullptr;
271 NAPI_CALL_DEFAULT(napi_create_double(env, value, &result));
272 return result;
273 }
274
275 template<class T>
CreateJsValue(napi_env env,const T & value)276 napi_value CreateJsValue(napi_env env, const T& value)
277 {
278 using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
279 napi_value result = nullptr;
280 if constexpr (std::is_same_v<ValueType, bool>) {
281 NAPI_CALL_DEFAULT(napi_get_boolean(env, value, &result));
282 return result;
283 } else if constexpr (std::is_arithmetic_v<ValueType>) {
284 return CreateJsNumber(env, value);
285 } else if constexpr (std::is_same_v<ValueType, std::string>) {
286 NAPI_CALL_DEFAULT(napi_create_string_utf8(env, value.c_str(), value.length(), &result));
287 return result;
288 } else if constexpr (std::is_enum_v<ValueType>) {
289 return CreateJsNumber(env, static_cast<std::make_signed_t<ValueType>>(value));
290 } else if constexpr (std::is_same_v<ValueType, const char*>) {
291 if (value != nullptr) {
292 NAPI_CALL_DEFAULT(napi_create_string_utf8(env, value, strlen(value), &result));
293 } else {
294 NAPI_CALL_DEFAULT(napi_get_undefined(env, &result));
295 }
296 return result;
297 } else {
298 return nullptr;
299 }
300 }
301
ConvertFromJsNumber(napi_env env,napi_value jsValue,int32_t & value)302 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int32_t& value)
303 {
304 return napi_get_value_int32(env, jsValue, &value) == napi_ok;
305 }
306
ConvertFromJsNumber(napi_env env,napi_value jsValue,uint32_t & value)307 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, uint32_t& value)
308 {
309 return napi_get_value_uint32(env, jsValue, &value) == napi_ok;
310 }
311
ConvertFromJsNumber(napi_env env,napi_value jsValue,int64_t & value)312 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int64_t& value)
313 {
314 return napi_get_value_int64(env, jsValue, &value) == napi_ok;
315 }
316
ConvertFromJsNumber(napi_env env,napi_value jsValue,double & value)317 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, double& value)
318 {
319 return napi_get_value_double(env, jsValue, &value) == napi_ok;
320 }
321
322 template<class T>
ConvertFromJsValue(napi_env env,napi_value jsValue,T & value)323 bool ConvertFromJsValue(napi_env env, napi_value jsValue, T& value)
324 {
325 if (jsValue == nullptr) {
326 return false;
327 }
328
329 using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
330 if constexpr (std::is_same_v<ValueType, bool>) {
331 return napi_get_value_bool(env, jsValue, &value) == napi_ok;
332 } else if constexpr (std::is_arithmetic_v<ValueType>) {
333 return ConvertFromJsNumber(env, jsValue, value);
334 } else if constexpr (std::is_same_v<ValueType, std::string>) {
335 size_t len = 0;
336 if (napi_get_value_string_utf8(env, jsValue, nullptr, 0, &len) != napi_ok) {
337 return false;
338 }
339 auto buffer = std::make_unique<char[]>(len + 1);
340 size_t strLength = 0;
341 if (napi_get_value_string_utf8(env, jsValue, buffer.get(), len + 1, &strLength) == napi_ok) {
342 value = buffer.get();
343 return true;
344 }
345 return false;
346 } else if constexpr (std::is_enum_v<ValueType>) {
347 std::make_signed_t<ValueType> numberValue = 0;
348 if (!ConvertFromJsNumber(env, jsValue, numberValue)) {
349 return false;
350 }
351 value = static_cast<ValueType>(numberValue);
352 return true;
353 }
354 return false;
355 }
356
357 napi_value CreateJsError(napi_env env, int32_t errCode, const std::string& message = std::string());
358 napi_status BindNativeFunction(napi_env env, napi_value object, const char* name,
359 const char* moduleName, napi_callback func);
360 bool CheckParamMinimumValid(napi_env env, const size_t paramNum, const size_t minNum);
361
362 napi_value ColorSpaceTypeInit(napi_env env);
363 napi_value CMErrorInit(napi_env env);
364 napi_value CMErrorCodeInit(napi_env env);
365 bool ParseJsDoubleValue(napi_value jsObject, napi_env env, const std::string& name, double& data);
366 } // namespace ColorManager
367 } // namespace OHOS
368 #endif // OHOS_JS_COLOR_SPACE_UTILS_H
369