1 /*
2 * Copyright (C) 2022 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 "sendable_pixel_map_napi.h"
17 #include <mutex>
18 #include "media_errors.h"
19 #include "image_log.h"
20 #include "image_napi_utils.h"
21 #include "image_pixel_map_napi.h"
22 #include "image_trace.h"
23 #include "log_tags.h"
24 #include "color_space_object_convertor.h"
25 #include "napi_message_sequence.h"
26 #include "hitrace_meter.h"
27 #include "pixel_map.h"
28 #include "transaction/rs_interfaces.h"
29 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
30 static int g_uniqueTid = 0;
31 #endif
32
33 #undef LOG_DOMAIN
34 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
35
36 #undef LOG_TAG
37 #define LOG_TAG "SendablePixelMapNapi"
38
39 namespace {
40 constexpr uint32_t NUM_0 = 0;
41 constexpr uint32_t NUM_1 = 1;
42 constexpr uint32_t NUM_2 = 2;
43 constexpr uint32_t NUM_3 = 3;
44 constexpr uint32_t NUM_4 = 4;
45 }
46
47 namespace OHOS {
48 namespace Media {
49 static const std::string CREATE_PIXEL_MAP_FROM_PARCEL = "CreateSendablPixelMapFromParcel";
50 static const std::string MARSHALLING = "marshalling";
51 static const std::map<std::string, std::set<uint32_t>> ETS_API_ERROR_CODE = {
52 {CREATE_PIXEL_MAP_FROM_PARCEL, {62980096, 62980105, 62980115, 62980097,
53 62980177, 62980178, 62980179, 62980180, 62980246}},
54 {MARSHALLING, {62980115, 62980097, 62980096}}
55 };
56 static const std::string CLASS_NAME = "SendablePixelMap";
57 static const std::int32_t NEW_INSTANCE_ARGC = 1;
58 thread_local napi_ref SendablePixelMapNapi::sConstructor_ = nullptr;
59 NAPI_MessageSequence* napi_messageSequence_sendable = nullptr;
60
61 std::shared_mutex SendablePixelMapNapi::mutex_;
62 static std::mutex pixelMapCrossThreadMutex_;
63 struct PositionArea {
64 void* pixels;
65 size_t size;
66 uint32_t offset;
67 uint32_t stride;
68 Rect region;
69 };
70
71 struct PixelMapAsyncContext {
72 napi_env env;
73 napi_async_work work;
74 napi_deferred deferred;
75 napi_ref callbackRef;
76 napi_ref error = nullptr;
77 uint32_t status;
78 SendablePixelMapNapi *nConstructor;
79 void* colorsBuffer;
80 size_t colorsBufferSize;
81 InitializationOptions opts;
82 PositionArea area;
83 std::shared_ptr<PixelMap> rPixelMap;
84 std::shared_ptr<PixelMap> alphaMap;
85 std::shared_ptr<PixelMap> wPixelMap;
86 double alpha = -1;
87 uint32_t resultUint32;
88 ImageInfo imageInfo;
89 double xArg = 0;
90 double yArg = 0;
91 bool xBarg = false;
92 bool yBarg = false;
93 std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace;
94 std::string surfaceId;
95 };
96
ParsePixlForamt(int32_t val)97 static PixelFormat ParsePixlForamt(int32_t val)
98 {
99 if (val <= static_cast<int32_t>(PixelFormat::CMYK)) {
100 return PixelFormat(val);
101 }
102
103 return PixelFormat::UNKNOWN;
104 }
105
ParseAlphaType(int32_t val)106 static AlphaType ParseAlphaType(int32_t val)
107 {
108 if (val <= static_cast<int32_t>(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
109 return AlphaType(val);
110 }
111
112 return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
113 }
114
ParseScaleMode(int32_t val)115 static ScaleMode ParseScaleMode(int32_t val)
116 {
117 if (val <= static_cast<int32_t>(ScaleMode::CENTER_CROP)) {
118 return ScaleMode(val);
119 }
120
121 return ScaleMode::FIT_TARGET_SIZE;
122 }
123
parseSize(napi_env env,napi_value root,Size * size)124 static bool parseSize(napi_env env, napi_value root, Size* size)
125 {
126 if (size == nullptr) {
127 return false;
128 }
129
130 if (!GET_INT32_BY_NAME(root, "height", size->height)) {
131 return false;
132 }
133
134 if (!GET_INT32_BY_NAME(root, "width", size->width)) {
135 return false;
136 }
137
138 return true;
139 }
140
parseInitializationOptions(napi_env env,napi_value root,InitializationOptions * opts)141 static bool parseInitializationOptions(napi_env env, napi_value root, InitializationOptions* opts)
142 {
143 uint32_t tmpNumber = 0;
144 napi_value tmpValue = nullptr;
145
146 if (opts == nullptr) {
147 return false;
148 }
149
150 if (!GET_BOOL_BY_NAME(root, "editable", opts->editable)) {
151 opts->editable = true;
152 }
153
154 if (!GET_UINT32_BY_NAME(root, "alphaType", tmpNumber)) {
155 IMAGE_LOGI("no alphaType in initialization options");
156 }
157 opts->alphaType = ParseAlphaType(tmpNumber);
158
159 tmpNumber = 0;
160 if (!GET_UINT32_BY_NAME(root, "pixelFormat", tmpNumber)) {
161 IMAGE_LOGI("no pixelFormat in initialization options");
162 }
163 opts->pixelFormat = ParsePixlForamt(tmpNumber);
164
165 tmpNumber = 0;
166 if (!GET_UINT32_BY_NAME(root, "srcPixelFormat", tmpNumber)) {
167 IMAGE_LOGI("no srcPixelFormat in initialization options");
168 }
169 opts->srcPixelFormat = ParsePixlForamt(tmpNumber);
170
171 tmpNumber = 0;
172 if (!GET_UINT32_BY_NAME(root, "scaleMode", tmpNumber)) {
173 IMAGE_LOGI("no scaleMode in initialization options");
174 }
175 opts->scaleMode = ParseScaleMode(tmpNumber);
176
177 if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
178 return false;
179 }
180
181 if (!parseSize(env, tmpValue, &(opts->size))) {
182 return false;
183 }
184 return true;
185 }
186
ParserImageType(napi_env env,napi_value argv)187 ImageType SendablePixelMapNapi::ParserImageType(napi_env env, napi_value argv)
188 {
189 napi_value constructor = nullptr;
190 napi_value global = nullptr;
191 bool isInstance = false;
192 napi_status ret = napi_invalid_arg;
193
194 napi_get_global(env, &global);
195
196 ret = napi_get_named_property(env, global, "PixelMap", &constructor);
197 if (ret != napi_ok) {
198 IMAGE_LOGI("Get SendablePixelMapNapi property failed!");
199 }
200
201 ret = napi_instanceof(env, argv, constructor, &isInstance);
202 if (ret == napi_ok && isInstance) {
203 return ImageType::TYPE_PIXEL_MAP;
204 }
205
206 IMAGE_LOGI("InValued type!");
207 return ImageType::TYPE_UNKNOWN;
208 }
209
parseRegion(napi_env env,napi_value root,Rect * region)210 static bool parseRegion(napi_env env, napi_value root, Rect* region)
211 {
212 napi_value tmpValue = nullptr;
213
214 if (region == nullptr) {
215 return false;
216 }
217
218 if (!GET_INT32_BY_NAME(root, "x", region->left)) {
219 return false;
220 }
221
222 if (!GET_INT32_BY_NAME(root, "y", region->top)) {
223 return false;
224 }
225
226 if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
227 return false;
228 }
229
230 if (!GET_INT32_BY_NAME(tmpValue, "height", region->height)) {
231 return false;
232 }
233
234 if (!GET_INT32_BY_NAME(tmpValue, "width", region->width)) {
235 return false;
236 }
237
238 return true;
239 }
240
parsePositionArea(napi_env env,napi_value root,PositionArea * area)241 static bool parsePositionArea(napi_env env, napi_value root, PositionArea* area)
242 {
243 napi_value tmpValue = nullptr;
244
245 if (area == nullptr) {
246 return false;
247 }
248
249 if (!GET_BUFFER_BY_NAME(root, "pixels", area->pixels, area->size)) {
250 return false;
251 }
252
253 if (!GET_UINT32_BY_NAME(root, "offset", area->offset)) {
254 return false;
255 }
256
257 if (!GET_UINT32_BY_NAME(root, "stride", area->stride)) {
258 return false;
259 }
260
261 if (!GET_NODE_BY_NAME(root, "region", tmpValue)) {
262 return false;
263 }
264
265 if (!parseRegion(env, tmpValue, &(area->region))) {
266 return false;
267 }
268 return true;
269 }
270
CommonCallbackRoutine(napi_env env,PixelMapAsyncContext * & asyncContext,const napi_value & valueParam)271 static void CommonCallbackRoutine(napi_env env, PixelMapAsyncContext* &asyncContext, const napi_value &valueParam)
272 {
273 napi_value result[NUM_2] = {0};
274 napi_value retVal;
275 napi_value callback = nullptr;
276
277 napi_get_undefined(env, &result[NUM_0]);
278 napi_get_undefined(env, &result[NUM_1]);
279
280 napi_handle_scope scope = nullptr;
281 napi_open_handle_scope(env, &scope);
282 if (scope == nullptr) {
283 return;
284 }
285
286 if (asyncContext == nullptr) {
287 napi_close_handle_scope(env, scope);
288 return;
289 }
290 if (asyncContext->status == SUCCESS) {
291 result[NUM_1] = valueParam;
292 } else if (asyncContext->error != nullptr) {
293 napi_get_reference_value(env, asyncContext->error, &result[NUM_0]);
294 napi_delete_reference(env, asyncContext->error);
295 } else {
296 napi_create_uint32(env, asyncContext->status, &result[NUM_0]);
297 }
298
299 if (asyncContext->deferred) {
300 if (asyncContext->status == SUCCESS) {
301 napi_resolve_deferred(env, asyncContext->deferred, result[NUM_1]);
302 } else {
303 napi_reject_deferred(env, asyncContext->deferred, result[NUM_0]);
304 }
305 } else {
306 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
307 napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
308 napi_delete_reference(env, asyncContext->callbackRef);
309 }
310
311 napi_delete_async_work(env, asyncContext->work);
312 napi_close_handle_scope(env, scope);
313
314 delete asyncContext;
315 asyncContext = nullptr;
316 }
317
NapiSendEvent(napi_env env,PixelMapAsyncContext * asyncContext,napi_event_priority prio,uint32_t status=SUCCESS)318 static void NapiSendEvent(napi_env env, PixelMapAsyncContext *asyncContext,
319 napi_event_priority prio, uint32_t status = SUCCESS)
320 {
321 if (napi_status::napi_ok != napi_send_event(env, [env, asyncContext, status]() {
322 if (!IMG_NOT_NULL(asyncContext)) {
323 IMAGE_LOGE("SendEvent asyncContext is nullptr!");
324 return;
325 }
326 napi_value result = nullptr;
327 napi_get_undefined(env, &result);
328 asyncContext->status = status;
329 PixelMapAsyncContext *context = asyncContext;
330 CommonCallbackRoutine(env, context, result);
331 }, prio)) {
332 IMAGE_LOGE("failed to sendEvent!");
333 }
334 }
335
STATIC_COMPLETE_FUNC(EmptyResult)336 STATIC_COMPLETE_FUNC(EmptyResult)
337 {
338 napi_value result = nullptr;
339 napi_get_undefined(env, &result);
340
341 auto context = static_cast<PixelMapAsyncContext*>(data);
342
343 CommonCallbackRoutine(env, context, result);
344 }
345
SendablePixelMapNapi()346 SendablePixelMapNapi::SendablePixelMapNapi():env_(nullptr)
347 {
348 static std::atomic<uint32_t> currentId = 0;
349 uniqueId_ = currentId.fetch_add(1, std::memory_order_relaxed);
350 }
351
~SendablePixelMapNapi()352 SendablePixelMapNapi::~SendablePixelMapNapi()
353 {
354 release();
355 }
356
DoInitAfter(napi_env env,napi_value exports,napi_value constructor,size_t property_count,const napi_property_descriptor * properties)357 static napi_value DoInitAfter(napi_env env,
358 napi_value exports,
359 napi_value constructor,
360 size_t property_count,
361 const napi_property_descriptor* properties)
362 {
363 napi_value global = nullptr;
364 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
365 napi_get_global(env, &global)),
366 nullptr, IMAGE_LOGE("Init:get global fail")
367 );
368
369 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
370 napi_set_named_property(env, global, CLASS_NAME.c_str(), constructor)),
371 nullptr, IMAGE_LOGE("Init:set global named property fail")
372 );
373
374 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
375 napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor)),
376 nullptr, IMAGE_LOGE("set named property fail")
377 );
378
379 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
380 napi_define_properties(env, exports, property_count, properties)),
381 nullptr, IMAGE_LOGE("define properties fail")
382 );
383 return exports;
384 }
385
Init(napi_env env,napi_value exports)386 napi_value SendablePixelMapNapi::Init(napi_env env, napi_value exports)
387 {
388 napi_property_descriptor props[] = {
389 DECLARE_NAPI_FUNCTION("readPixelsToBuffer", ReadPixelsToBuffer),
390 DECLARE_NAPI_FUNCTION("readPixelsToBufferSync", ReadPixelsToBufferSync),
391 DECLARE_NAPI_FUNCTION("readPixels", ReadPixels),
392 DECLARE_NAPI_FUNCTION("readPixelsSync", ReadPixelsSync),
393 DECLARE_NAPI_FUNCTION("writePixels", WritePixels),
394 DECLARE_NAPI_FUNCTION("writePixelsSync", WritePixelsSync),
395 DECLARE_NAPI_FUNCTION("writeBufferToPixels", WriteBufferToPixels),
396 DECLARE_NAPI_FUNCTION("writeBufferToPixelsSync", WriteBufferToPixelsSync),
397 DECLARE_NAPI_FUNCTION("getImageInfo", GetImageInfo),
398 DECLARE_NAPI_FUNCTION("getImageInfoSync", GetImageInfoSync),
399 DECLARE_NAPI_FUNCTION("getBytesNumberPerRow", GetBytesNumberPerRow),
400 DECLARE_NAPI_FUNCTION("getPixelBytesNumber", GetPixelBytesNumber),
401 DECLARE_NAPI_FUNCTION("isSupportAlpha", IsSupportAlpha),
402 DECLARE_NAPI_FUNCTION("setAlphaAble", SetAlphaAble),
403 DECLARE_NAPI_FUNCTION("createAlphaPixelmap", CreateAlphaPixelmap),
404 DECLARE_NAPI_FUNCTION("createAlphaPixelmapSync", CreateAlphaPixelmapSync),
405 DECLARE_NAPI_FUNCTION("getDensity", GetDensity),
406 DECLARE_NAPI_FUNCTION("setDensity", SetDensity),
407 DECLARE_NAPI_FUNCTION("opacity", SetAlpha),
408 DECLARE_NAPI_FUNCTION("opacitySync", SetAlphaSync),
409 DECLARE_NAPI_FUNCTION("release", Release),
410 DECLARE_NAPI_FUNCTION("scale", Scale),
411 DECLARE_NAPI_FUNCTION("scaleSync", ScaleSync),
412 DECLARE_NAPI_FUNCTION("translate", Translate),
413 DECLARE_NAPI_FUNCTION("translateSync", TranslateSync),
414 DECLARE_NAPI_FUNCTION("rotate", Rotate),
415 DECLARE_NAPI_FUNCTION("rotateSync", RotateSync),
416 DECLARE_NAPI_FUNCTION("flip", Flip),
417 DECLARE_NAPI_FUNCTION("flipSync", FlipSync),
418 DECLARE_NAPI_FUNCTION("crop", Crop),
419 DECLARE_NAPI_FUNCTION("cropSync", CropSync),
420 DECLARE_NAPI_FUNCTION("getColorSpace", GetColorSpace),
421 DECLARE_NAPI_FUNCTION("setColorSpace", SetColorSpace),
422 DECLARE_NAPI_FUNCTION("applyColorSpace", ApplyColorSpace),
423 DECLARE_NAPI_FUNCTION("marshalling", Marshalling),
424 DECLARE_NAPI_FUNCTION("unmarshalling", Unmarshalling),
425 DECLARE_NAPI_GETTER("isEditable", GetIsEditable),
426 DECLARE_NAPI_GETTER("isStrideAlignment", GetIsStrideAlignment),
427 };
428
429 napi_property_descriptor static_prop[] = {
430 DECLARE_NAPI_STATIC_FUNCTION("createPixelMap", CreateSendablePixelMap),
431 DECLARE_NAPI_STATIC_FUNCTION("createPremultipliedPixelMap", CreatePremultipliedSendablePixelMap),
432 DECLARE_NAPI_STATIC_FUNCTION("createUnpremultipliedPixelMap", CreateUnpremultipliedSendablePixelMap),
433 DECLARE_NAPI_STATIC_FUNCTION("createPixelMapSync", CreateSendablePixelMapSync),
434 DECLARE_NAPI_STATIC_FUNCTION("unmarshalling", Unmarshalling),
435 DECLARE_NAPI_STATIC_FUNCTION("createPixelMapFromParcel", CreateSendablPixelMapFromParcel),
436 DECLARE_NAPI_STATIC_FUNCTION("createPixelMapFromSurface", CreateSendablePixelMapFromSurface),
437 DECLARE_NAPI_STATIC_FUNCTION("convertFromPixelMap", ConvertFromPixelMap),
438 DECLARE_NAPI_STATIC_FUNCTION("convertToPixelMap", ConvertToPixelMap),
439 };
440
441 napi_value constructor = nullptr;
442
443 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
444 napi_define_sendable_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
445 Constructor, nullptr, IMG_ARRAY_SIZE(props), props, nullptr, &constructor)),
446 nullptr, IMAGE_LOGE("define class fail")
447 );
448
449 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
450 napi_create_reference(env, constructor, 1, &sConstructor_)),
451 nullptr, IMAGE_LOGE("create reference fail")
452 );
453
454 auto result = DoInitAfter(env, exports, constructor,
455 IMG_ARRAY_SIZE(static_prop), static_prop);
456
457 IMAGE_LOGD("Init success");
458 return result;
459 }
460
NapiUnwrap(napi_env env,napi_value object,void ** result,bool isSendable=true)461 static napi_status NapiUnwrap(napi_env env, napi_value object, void** result, bool isSendable = true)
462 {
463 napi_status status = napi_invalid_arg;
464 if (isSendable) {
465 status = napi_unwrap_sendable(env, object, result);
466 if (!IMG_IS_OK(status)) {
467 IMAGE_LOGE("NapiUnwrap napi_unwrap_sendable failed");
468 }
469 } else {
470 status = napi_unwrap(env, object, result);
471 if (!IMG_IS_OK(status)) {
472 IMAGE_LOGE("NapiUnwrap napi_unwrap failed");
473 }
474 }
475 return status;
476 }
477
GetSendablePixelMap(napi_env env,napi_value pixelmap)478 std::shared_ptr<PixelMap> SendablePixelMapNapi::GetSendablePixelMap(napi_env env, napi_value pixelmap)
479 {
480 std::unique_ptr<SendablePixelMapNapi> pixelMapNapi = nullptr;
481
482 napi_status status = NapiUnwrap(env, pixelmap, reinterpret_cast<void**>(&pixelMapNapi));
483 if (!IMG_IS_OK(status)) {
484 IMAGE_LOGE("GetPixelMap napi unwrap failed");
485 return nullptr;
486 }
487 IMG_NAPI_CHECK_RET_D(IMG_NOT_NULL(pixelMapNapi), nullptr,
488 IMAGE_LOGE("GetPixelMap pixmapNapi is nullptr"));
489
490 auto pixelmapNapiPtr = pixelMapNapi.release();
491 if (pixelmapNapiPtr == nullptr) {
492 IMAGE_LOGE("GetPixelMap SendablePixelMapNapi is nullptr");
493 return nullptr;
494 }
495 return pixelmapNapiPtr->nativePixelMap_;
496 }
497
IsLockPixelMap()498 bool SendablePixelMapNapi::IsLockPixelMap()
499 {
500 return (lockCount > 0);
501 }
502
LockPixelMap()503 bool SendablePixelMapNapi::LockPixelMap()
504 {
505 lockCount++;
506 return true;
507 }
508
UnlockPixelMap()509 void SendablePixelMapNapi::UnlockPixelMap()
510 {
511 if (lockCount > 0) {
512 lockCount--;
513 }
514 }
515
NewPixelNapiInstance(napi_env & env,napi_value & constructor,std::shared_ptr<PixelMap> & pixelMap,napi_value & result)516 static napi_status NewPixelNapiInstance(napi_env &env, napi_value &constructor,
517 std::shared_ptr<PixelMap> &pixelMap, napi_value &result)
518 {
519 napi_status status;
520 if (pixelMap == nullptr) {
521 status = napi_invalid_arg;
522 IMAGE_LOGE("NewPixelNapiInstance pixelMap is nullptr");
523 return status;
524 }
525 size_t argc = NEW_INSTANCE_ARGC;
526 napi_value argv[NEW_INSTANCE_ARGC] = { 0 };
527
528 uint64_t pixelMapId;
529 uint64_t UNIQUE_ID_SHIFT = 32;
530 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
531 pixelMapId = (static_cast<uint64_t>(pixelMap->GetUniqueId()) << UNIQUE_ID_SHIFT) |
532 static_cast<uint64_t>(g_uniqueTid++);
533 #else
534 pixelMapId = (static_cast<uint64_t>(pixelMap->GetUniqueId()) << UNIQUE_ID_SHIFT) | static_cast<uint64_t>(gettid());
535 #endif
536 status = napi_create_bigint_uint64(env, pixelMapId, &argv[0]);
537 if (!IMG_IS_OK(status)) {
538 IMAGE_LOGE("NewPixelNapiInstance napi_create_bigint_uint64 failed");
539 return status;
540 }
541 PixelMapContainer::GetInstance().Insert(pixelMapId, pixelMap);
542
543 status = napi_new_instance(env, constructor, argc, argv, &result);
544 return status;
545 }
546
Constructor(napi_env env,napi_callback_info info)547 napi_value SendablePixelMapNapi::Constructor(napi_env env, napi_callback_info info)
548 {
549 napi_value undefineVar = nullptr;
550 napi_get_undefined(env, &undefineVar);
551
552 napi_status status;
553 napi_value thisVar = nullptr;
554 napi_get_undefined(env, &thisVar);
555 size_t argc = NEW_INSTANCE_ARGC;
556 napi_value argv[NEW_INSTANCE_ARGC] = { 0 };
557 IMAGE_LOGD("Constructor IN");
558 status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
559 IMG_NAPI_CHECK_RET(IMG_IS_READY(status, thisVar), undefineVar);
560 uint64_t pixelMapId = 0;
561 bool lossless = true;
562 if (!IMG_IS_OK(napi_get_value_bigint_uint64(env, argv[0], &pixelMapId, &lossless))) {
563 IMAGE_LOGE("Constructor napi_get_value_bigint_uint64 failed");
564 return undefineVar;
565 }
566 std::unique_ptr<SendablePixelMapNapi> pPixelMapNapi = std::make_unique<SendablePixelMapNapi>();
567
568 IMG_NAPI_CHECK_RET(IMG_NOT_NULL(pPixelMapNapi), undefineVar);
569
570 pPixelMapNapi->env_ = env;
571 if (PixelMapContainer::GetInstance().Find(pixelMapId)) {
572 pPixelMapNapi->nativePixelMap_ = PixelMapContainer::GetInstance()[pixelMapId];
573 IMAGE_LOGD("Constructor in napi_id:%{public}d, id:%{public}d",
574 pPixelMapNapi->GetUniqueId(), pPixelMapNapi->nativePixelMap_->GetUniqueId());
575 } else {
576 IMAGE_LOGE("Constructor nativePixelMap is nullptr");
577 }
578
579 status = napi_wrap_sendable(env, thisVar, reinterpret_cast<void*>(pPixelMapNapi.get()),
580 SendablePixelMapNapi::Destructor, nullptr);
581 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), undefineVar, IMAGE_LOGE("Failure wrapping js to native napi"));
582
583 pPixelMapNapi.release();
584 PixelMapContainer::GetInstance().Erase(pixelMapId);
585 return thisVar;
586 }
587
Destructor(napi_env env,void * nativeObject,void * finalize)588 void SendablePixelMapNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
589 {
590 if (nativeObject != nullptr) {
591 std::lock_guard<std::mutex> lock(pixelMapCrossThreadMutex_);
592 IMAGE_LOGD("Destructor SendablePixelMapNapi");
593 delete reinterpret_cast<SendablePixelMapNapi*>(nativeObject);
594 nativeObject = nullptr;
595 }
596 }
597
BuildContextError(napi_env env,napi_ref & error,const std::string errMsg,const int32_t errCode)598 static void BuildContextError(napi_env env, napi_ref &error, const std::string errMsg, const int32_t errCode)
599 {
600 IMAGE_LOGE("%{public}s", errMsg.c_str());
601 napi_value tmpError;
602 ImageNapiUtils::CreateErrorObj(env, tmpError, errCode, errMsg);
603 napi_create_reference(env, tmpError, NUM_1, &(error));
604 }
605
STATIC_EXEC_FUNC(CreateSendablePixelMap)606 STATIC_EXEC_FUNC(CreateSendablePixelMap)
607 {
608 auto context = static_cast<PixelMapAsyncContext*>(data);
609 auto colors = static_cast<uint32_t*>(context->colorsBuffer);
610 if (context->opts.pixelFormat == PixelFormat::RGBA_1010102 ||
611 context->opts.pixelFormat == PixelFormat::YCBCR_P010 ||
612 context->opts.pixelFormat == PixelFormat::YCRCB_P010) {
613 context->rPixelMap = nullptr;
614 } else {
615 if (colors == nullptr) {
616 auto pixelmap = PixelMap::Create(context->opts);
617 context->rPixelMap = std::move(pixelmap);
618 } else {
619 auto pixelmap = PixelMap::Create(colors, context->colorsBufferSize, context->opts);
620 context->rPixelMap = std::move(pixelmap);
621 }
622 }
623
624 if (IMG_NOT_NULL(context->rPixelMap)) {
625 context->status = SUCCESS;
626 } else {
627 context->status = ERROR;
628 }
629 }
630
CreateSendablePixelMapComplete(napi_env env,napi_status status,void * data)631 void SendablePixelMapNapi::CreateSendablePixelMapComplete(napi_env env, napi_status status, void *data)
632 {
633 napi_value constructor = nullptr;
634 napi_value result = nullptr;
635
636 IMAGE_LOGD("CreatePixelMapComplete IN");
637 auto context = static_cast<PixelMapAsyncContext*>(data);
638 status = napi_get_reference_value(env, sConstructor_, &constructor);
639 if (IMG_IS_OK(status)) {
640 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
641 }
642 if (!IMG_IS_OK(status)) {
643 context->status = ERROR;
644 IMAGE_LOGE("New instance could not be obtained");
645 napi_get_undefined(env, &result);
646 }
647 CommonCallbackRoutine(env, context, result);
648 }
649
STATIC_EXEC_FUNC(CreatePremultipliedPixelMap)650 STATIC_EXEC_FUNC(CreatePremultipliedPixelMap)
651 {
652 auto context = static_cast<PixelMapAsyncContext*>(data);
653 if (IMG_NOT_NULL(context->rPixelMap) && IMG_NOT_NULL(context->wPixelMap)) {
654 bool isPremul = true;
655 if (context->wPixelMap->IsEditable()) {
656 context->status = context->rPixelMap->ConvertAlphaFormat(*context->wPixelMap.get(), isPremul);
657 } else {
658 context->status = ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
659 }
660 } else {
661 context->status = ERR_IMAGE_READ_PIXELMAP_FAILED;
662 }
663 }
664
STATIC_EXEC_FUNC(CreateUnpremultipliedPixelMap)665 STATIC_EXEC_FUNC(CreateUnpremultipliedPixelMap)
666 {
667 auto context = static_cast<PixelMapAsyncContext*>(data);
668 if (IMG_NOT_NULL(context->rPixelMap) && IMG_NOT_NULL(context->wPixelMap)) {
669 bool isPremul = false;
670 if (context->wPixelMap->IsEditable()) {
671 context->status = context->rPixelMap->ConvertAlphaFormat(*context->wPixelMap.get(), isPremul);
672 } else {
673 context->status = ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
674 }
675 } else {
676 context->status = ERR_IMAGE_READ_PIXELMAP_FAILED;
677 }
678 }
679
CreatePremultipliedSendablePixelMap(napi_env env,napi_callback_info info)680 napi_value SendablePixelMapNapi::CreatePremultipliedSendablePixelMap(napi_env env, napi_callback_info info)
681 {
682 napi_value result = nullptr;
683 napi_get_undefined(env, &result);
684 int32_t refCount = 1;
685 napi_status status;
686 napi_value thisVar = nullptr;
687 napi_value argValue[NUM_3] = {0};
688 size_t argCount = NUM_3;
689 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
690
691 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
692 IMG_NAPI_CHECK_RET_D(argCount >= NUM_2,
693 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
694 "Invalid args count"),
695 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
696 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
697
698 if (ParserImageType(env, argValue[NUM_0]) == ImageType::TYPE_PIXEL_MAP &&
699 ParserImageType(env, argValue[NUM_1]) == ImageType::TYPE_PIXEL_MAP) {
700 asyncContext->rPixelMap = GetSendablePixelMap(env, argValue[NUM_0]);
701 asyncContext->wPixelMap = GetSendablePixelMap(env, argValue[NUM_1]);
702 if (asyncContext->rPixelMap == nullptr || asyncContext->wPixelMap == nullptr) {
703 BuildContextError(env, asyncContext->error, "input image type mismatch", ERR_IMAGE_GET_DATA_ABNORMAL);
704 }
705 } else {
706 BuildContextError(env, asyncContext->error, "input image type mismatch",
707 ERR_IMAGE_GET_DATA_ABNORMAL);
708 }
709
710 IMG_NAPI_CHECK_RET_D(asyncContext->error == nullptr, nullptr, IMAGE_LOGE("input image type mismatch"));
711 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
712 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
713 }
714 if (asyncContext->callbackRef == nullptr) {
715 napi_create_promise(env, &(asyncContext->deferred), &result);
716 }
717
718 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->error == nullptr,
719 BuildContextError(env, asyncContext->error, "CreatePremultipliedPixelMapError", ERR_IMAGE_GET_DATA_ABNORMAL),
720 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_IMAGE_GET_DATA_ABNORMAL),
721 result);
722
723 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePremultipliedPixelMap",
724 CreatePremultipliedPixelMapExec, EmptyResultComplete, asyncContext, asyncContext->work);
725
726 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
727 IMAGE_LOGE("fail to create async work");
728 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
729 });
730 return result;
731 }
732
CreateUnpremultipliedSendablePixelMap(napi_env env,napi_callback_info info)733 napi_value SendablePixelMapNapi::CreateUnpremultipliedSendablePixelMap(napi_env env, napi_callback_info info)
734 {
735 napi_value result = nullptr;
736 napi_get_undefined(env, &result);
737 int32_t refCount = 1;
738 napi_status status;
739 napi_value thisVar = nullptr;
740 napi_value argValue[NUM_3] = {0};
741 size_t argCount = NUM_3;
742 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
743
744 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
745 IMG_NAPI_CHECK_RET_D(argCount >= NUM_2,
746 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
747 "Invalid args count"),
748 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
749 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
750
751 if (ParserImageType(env, argValue[NUM_0]) == ImageType::TYPE_PIXEL_MAP &&
752 ParserImageType(env, argValue[NUM_1]) == ImageType::TYPE_PIXEL_MAP) {
753 asyncContext->rPixelMap = GetSendablePixelMap(env, argValue[NUM_0]);
754 asyncContext->wPixelMap = GetSendablePixelMap(env, argValue[NUM_1]);
755 if (asyncContext->rPixelMap == nullptr || asyncContext->wPixelMap == nullptr) {
756 BuildContextError(env, asyncContext->error, "input image type mismatch", ERR_IMAGE_GET_DATA_ABNORMAL);
757 }
758 } else {
759 BuildContextError(env, asyncContext->error, "input image type mismatch",
760 ERR_IMAGE_GET_DATA_ABNORMAL);
761 }
762
763 IMG_NAPI_CHECK_RET_D(asyncContext->error == nullptr, nullptr, IMAGE_LOGE("input image type mismatch"));
764 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
765 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
766 }
767 if (asyncContext->callbackRef == nullptr) {
768 napi_create_promise(env, &(asyncContext->deferred), &result);
769 }
770
771 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->error == nullptr,
772 BuildContextError(env, asyncContext->error, "CreateUnpremultipliedPixelMapError", ERR_IMAGE_GET_DATA_ABNORMAL),
773 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_IMAGE_GET_DATA_ABNORMAL),
774 result);
775
776 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateUnpremultipliedPixelMap",
777 CreateUnpremultipliedPixelMapExec, EmptyResultComplete, asyncContext, asyncContext->work);
778
779 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
780 IMAGE_LOGE("fail to create async work");
781 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
782 });
783 return result;
784 }
785
CreateSendablePixelMap(napi_env env,napi_callback_info info)786 napi_value SendablePixelMapNapi::CreateSendablePixelMap(napi_env env, napi_callback_info info)
787 {
788 if (SendablePixelMapNapi::GetConstructor() == nullptr) {
789 napi_value exports = nullptr;
790 napi_create_object(env, &exports);
791 SendablePixelMapNapi::Init(env, exports);
792 }
793
794 napi_value result = nullptr;
795 napi_get_undefined(env, &result);
796
797 int32_t refCount = 1;
798
799 napi_status status;
800 napi_value thisVar = nullptr;
801 napi_value argValue[NUM_4] = {0};
802 size_t argCount = NUM_4;
803 IMAGE_LOGD("CreateSendablePixelMap IN");
804
805 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
806
807 // we are static method!
808 // thisVar is nullptr here
809 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
810 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
811
812 status = napi_get_arraybuffer_info(env, argValue[NUM_0], &(asyncContext->colorsBuffer),
813 &(asyncContext->colorsBufferSize));
814
815 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
816
817 IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[1], &(asyncContext->opts)),
818 nullptr, IMAGE_LOGE("InitializationOptions mismatch"));
819
820 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
821 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
822 }
823
824 if (asyncContext->callbackRef == nullptr) {
825 napi_create_promise(env, &(asyncContext->deferred), &result);
826 } else {
827 napi_get_undefined(env, &result);
828 }
829
830 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateSendablePixelMap",
831 CreateSendablePixelMapExec, CreateSendablePixelMapComplete, asyncContext, asyncContext->work);
832
833 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
834 IMAGE_LOGE("fail to create async work");
835 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
836 });
837 return result;
838 }
839
ConvertFromPixelMap(napi_env env,napi_callback_info info)840 napi_value SendablePixelMapNapi::ConvertFromPixelMap(napi_env env, napi_callback_info info)
841 {
842 if (SendablePixelMapNapi::GetConstructor() == nullptr) {
843 napi_value exports = nullptr;
844 napi_create_object(env, &exports);
845 SendablePixelMapNapi::Init(env, exports);
846 }
847
848 napi_value result = nullptr;
849 napi_get_undefined(env, &result);
850 napi_status status;
851 napi_value thisVar = nullptr;
852 napi_value argValue[NUM_2] = {0};
853 size_t argCount = NUM_2;
854 IMAGE_LOGD("ConvertFromPixelMap IN2");
855 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
856 if (!IMG_IS_OK(status)) {
857 return ImageNapiUtils::ThrowExceptionError(env,
858 COMMON_ERR_INVALID_PARAMETER, "ConvertFromPixelMap Invalid parameter");
859 }
860 PixelMapNapi* pixelMapNapi = nullptr;
861 NapiUnwrap(env, argValue[0], reinterpret_cast<void**>(&pixelMapNapi), false);
862 if (!(IMG_NOT_NULL(pixelMapNapi) && IMG_NOT_NULL(pixelMapNapi->GetPixelNapiInner()))) {
863 return ImageNapiUtils::ThrowExceptionError(env,
864 ERR_IMAGE_INIT_ABNORMAL, "ConvertFromPixelMap napi_unwrap failed");
865 }
866
867 std::shared_ptr<PixelMap> nativePixelMap = pixelMapNapi->GetPixelNapiInner();
868 pixelMapNapi->ReleasePixelNapiInner();
869 result = CreateSendablePixelMap(env, nativePixelMap);
870 if (!IMG_NOT_NULL(result)) {
871 return ImageNapiUtils::ThrowExceptionError(env,
872 ERR_IMAGE_INIT_ABNORMAL, "ConvertFromPixelMap wrap failed");
873 }
874 return result;
875 }
876
ConvertToPixelMap(napi_env env,napi_callback_info info)877 napi_value SendablePixelMapNapi::ConvertToPixelMap(napi_env env, napi_callback_info info)
878 {
879 if (SendablePixelMapNapi::GetConstructor() == nullptr) {
880 napi_value exports = nullptr;
881 napi_create_object(env, &exports);
882 SendablePixelMapNapi::Init(env, exports);
883 }
884
885 napi_value result = nullptr;
886 napi_get_undefined(env, &result);
887 napi_status status;
888 napi_value thisVar = nullptr;
889 napi_value argValue[NUM_2] = {0};
890 size_t argCount = NUM_2;
891 IMAGE_LOGD("ConvertToPixelMap IN");
892 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
893 if (!IMG_IS_OK(status)) {
894 return ImageNapiUtils::ThrowExceptionError(env,
895 COMMON_ERR_INVALID_PARAMETER, "ConvertToPixelMap Invalid parameter");
896 }
897 SendablePixelMapNapi* pixelMapNapi = nullptr;
898 NapiUnwrap(env, argValue[0], reinterpret_cast<void**>(&pixelMapNapi));
899 if (!(IMG_NOT_NULL(pixelMapNapi) && IMG_NOT_NULL(pixelMapNapi->nativePixelMap_))) {
900 return ImageNapiUtils::ThrowExceptionError(env,
901 ERR_IMAGE_INIT_ABNORMAL, "ConvertToPixelMap napi_unwrap failed");
902 }
903
904 std::shared_ptr<PixelMap> nativePixelMap = pixelMapNapi->nativePixelMap_;
905 pixelMapNapi->ReleasePixelNapiInner();
906 result = PixelMapNapi::CreatePixelMap(env, nativePixelMap);
907 if (!IMG_NOT_NULL(result)) {
908 return ImageNapiUtils::ThrowExceptionError(env,
909 ERR_IMAGE_INIT_ABNORMAL, "ConvertToPixelMap wrap failed");
910 }
911 return result;
912 }
913
CreateSendablePixelMapSync(napi_env env,napi_callback_info info)914 napi_value SendablePixelMapNapi::CreateSendablePixelMapSync(napi_env env, napi_callback_info info)
915 {
916 if (SendablePixelMapNapi::GetConstructor() == nullptr) {
917 napi_value exports = nullptr;
918 napi_create_object(env, &exports);
919 SendablePixelMapNapi::Init(env, exports);
920 }
921
922 napi_value result = nullptr;
923 napi_get_undefined(env, &result);
924 napi_value constructor = nullptr;
925 napi_status status;
926 napi_value thisVar = nullptr;
927 napi_value argValue[NUM_2] = {0};
928 size_t argCount = NUM_2;
929 IMAGE_LOGD("CreatePixelMap IN");
930
931 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
932
933 // we are static method!
934 // thisVar is nullptr here
935 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
936
937 IMG_NAPI_CHECK_RET_D(argCount == NUM_2 || argCount == NUM_1,
938 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
939 "Invalid args count"),
940 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
941 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
942
943 if (argCount == NUM_2) {
944 status = napi_get_arraybuffer_info(env, argValue[NUM_0], &(asyncContext->colorsBuffer),
945 &(asyncContext->colorsBufferSize));
946 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
947 IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[1], &(asyncContext->opts)),
948 nullptr, IMAGE_LOGE("InitializationOptions mismatch"));
949 } else if (argCount == NUM_1) {
950 IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[NUM_0], &(asyncContext->opts)),
951 nullptr, IMAGE_LOGE("InitializationOptions mismatch"));
952 }
953 CreateSendablePixelMapExec(env, static_cast<void*>((asyncContext).get()));
954 status = napi_get_reference_value(env, sConstructor_, &constructor);
955 if (IMG_IS_OK(status)) {
956 status = NewPixelNapiInstance(env, constructor, asyncContext->rPixelMap, result);
957 }
958 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to create pixel map sync"));
959 return result;
960 }
961
962 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
STATIC_EXEC_FUNC(CreateSendablePixelMapFromSurface)963 STATIC_EXEC_FUNC(CreateSendablePixelMapFromSurface)
964 {
965 auto context = static_cast<PixelMapAsyncContext*>(data);
966 IMAGE_LOGD("CreateSendablePixelMapFromSurface id:%{public}s,area:%{public}d,%{public}d,%{public}d,%{public}d",
967 context->surfaceId.c_str(), context->area.region.left, context->area.region.top,
968 context->area.region.height, context->area.region.width);
969
970 auto &rsClient = Rosen::RSInterfaces::GetInstance();
971 OHOS::Rect r = {
972 .x = context->area.region.left,
973 .y = context->area.region.top,
974 .w = context->area.region.width,
975 .h = context->area.region.height,
976 };
977 std::shared_ptr<Media::PixelMap> pixelMap =
978 rsClient.CreatePixelMapFromSurfaceId(std::stoull(context->surfaceId), r);
979 context->rPixelMap = std::move(pixelMap);
980
981 if (IMG_NOT_NULL(context->rPixelMap)) {
982 context->status = SUCCESS;
983 } else {
984 context->status = ERR_IMAGE_INVALID_PARAMETER;
985 }
986 }
987
CreateSendablePixelMapFromSurfaceComplete(napi_env env,napi_status status,void * data)988 void SendablePixelMapNapi::CreateSendablePixelMapFromSurfaceComplete(napi_env env, napi_status status, void *data)
989 {
990 napi_value constructor = nullptr;
991 napi_value result = nullptr;
992
993 IMAGE_LOGD("CreateSendablePixelMapFromSurface IN");
994 auto context = static_cast<PixelMapAsyncContext*>(data);
995 status = napi_get_reference_value(env, sConstructor_, &constructor);
996 if (IMG_IS_OK(status)) {
997 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
998 }
999 if (!IMG_IS_OK(status)) {
1000 context->status = ERR_IMAGE_PIXELMAP_CREATE_FAILED;
1001 IMAGE_LOGE("New instance could not be obtained");
1002 napi_get_undefined(env, &result);
1003 }
1004 CommonCallbackRoutine(env, context, result);
1005 }
1006
GetStringArgument(napi_env env,napi_value value)1007 static std::string GetStringArgument(napi_env env, napi_value value)
1008 {
1009 std::string strValue = "";
1010 size_t bufLength = 0;
1011 napi_status status = napi_get_value_string_utf8(env, value, nullptr, NUM_0, &bufLength);
1012 if (status == napi_ok && bufLength > NUM_0 && bufLength < PATH_MAX) {
1013 char *buffer = reinterpret_cast<char *>(malloc((bufLength + NUM_1) * sizeof(char)));
1014 if (buffer == nullptr) {
1015 IMAGE_LOGE("No memory");
1016 return strValue;
1017 }
1018
1019 status = napi_get_value_string_utf8(env, value, buffer, bufLength + NUM_1, &bufLength);
1020 if (status == napi_ok) {
1021 IMAGE_LOGD("Get Success");
1022 strValue.assign(buffer, 0, bufLength + NUM_1);
1023 }
1024 if (buffer != nullptr) {
1025 free(buffer);
1026 buffer = nullptr;
1027 }
1028 }
1029 return strValue;
1030 }
1031
CreateSendablePixelMapFromSurface(napi_env env,napi_callback_info info)1032 napi_value SendablePixelMapNapi::CreateSendablePixelMapFromSurface(napi_env env, napi_callback_info info)
1033 {
1034 napi_value globalValue;
1035 napi_get_global(env, &globalValue);
1036 napi_value func;
1037 napi_get_named_property(env, globalValue, "requireNapi", &func);
1038
1039 napi_value imageInfo;
1040 napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
1041 napi_value funcArgv[1] = { imageInfo };
1042 napi_value returnValue;
1043 napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
1044
1045 napi_value result = nullptr;
1046 napi_get_undefined(env, &result);
1047 int32_t refCount = 1;
1048 napi_status status;
1049 napi_value thisVar = nullptr;
1050 napi_value argValue[NUM_4] = {0};
1051 size_t argCount = NUM_4;
1052 IMAGE_LOGD("CreateSendablePixelMapFromSurface IN");
1053 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1054 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1055 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1056 asyncContext->surfaceId = GetStringArgument(env, argValue[NUM_0]);
1057 bool ret = parseRegion(env, argValue[NUM_1], &(asyncContext->area.region));
1058 IMAGE_LOGD("CreateSendablePixelMapFromSurface get data: %{public}d", ret);
1059 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1060 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1061 }
1062 if (asyncContext->callbackRef == nullptr) {
1063 napi_create_promise(env, &(asyncContext->deferred), &result);
1064 } else {
1065 napi_get_undefined(env, &result);
1066 }
1067 IMG_NAPI_CHECK_BUILD_ERROR(ret,
1068 BuildContextError(env, asyncContext->error, "image invalid parameter", ERR_IMAGE_GET_DATA_ABNORMAL),
1069 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_IMAGE_GET_DATA_ABNORMAL),
1070 result);
1071 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateSendablePixelMapFromSurface",
1072 CreateSendablePixelMapFromSurfaceExec, CreateSendablePixelMapFromSurfaceComplete,
1073 asyncContext, asyncContext->work);
1074 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
1075 IMAGE_LOGE("fail to create async work");
1076 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
1077 });
1078 return result;
1079 }
1080 #endif
CreateSendablePixelMap(napi_env env,std::shared_ptr<PixelMap> pixelmap)1081 napi_value SendablePixelMapNapi::CreateSendablePixelMap(napi_env env, std::shared_ptr<PixelMap> pixelmap)
1082
1083 {
1084 if (SendablePixelMapNapi::GetConstructor() == nullptr) {
1085 napi_value exports = nullptr;
1086 napi_create_object(env, &exports);
1087 SendablePixelMapNapi::Init(env, exports);
1088 }
1089 napi_value constructor = nullptr;
1090 napi_value result = nullptr;
1091 napi_status status;
1092 IMAGE_LOGD("CreatePixelMap IN");
1093 status = napi_get_reference_value(env, sConstructor_, &constructor);
1094 if (IMG_IS_OK(status)) {
1095 status = NewPixelNapiInstance(env, constructor, pixelmap, result);
1096 }
1097 if (!IMG_IS_OK(status)) {
1098 IMAGE_LOGE("CreatePixelMap | New instance could not be obtained");
1099 napi_get_undefined(env, &result);
1100 }
1101 return result;
1102 }
1103
STATIC_EXEC_FUNC(Unmarshalling)1104 STATIC_EXEC_FUNC(Unmarshalling)
1105 {
1106 auto context = static_cast<PixelMapAsyncContext*>(data);
1107
1108 auto messageParcel = napi_messageSequence_sendable->GetMessageParcel();
1109 auto pixelmap = PixelMap::Unmarshalling(*messageParcel);
1110 std::unique_ptr<OHOS::Media::PixelMap> pixelmap_ptr(pixelmap);
1111
1112 context->rPixelMap = std::move(pixelmap_ptr);
1113
1114 if (IMG_NOT_NULL(context->rPixelMap)) {
1115 context->status = SUCCESS;
1116 } else {
1117 context->status = ERROR;
1118 }
1119 }
1120
UnmarshallingComplete(napi_env env,napi_status status,void * data)1121 void SendablePixelMapNapi::UnmarshallingComplete(napi_env env, napi_status status, void *data)
1122 {
1123 napi_value constructor = nullptr;
1124 napi_value result = nullptr;
1125
1126 IMAGE_LOGD("UnmarshallingComplete IN");
1127 auto context = static_cast<PixelMapAsyncContext*>(data);
1128
1129 status = napi_get_reference_value(env, sConstructor_, &constructor);
1130 if (IMG_IS_OK(status)) {
1131 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
1132 }
1133
1134 if (!IMG_IS_OK(status)) {
1135 context->status = ERROR;
1136 IMAGE_LOGE("New instance could not be obtained");
1137 napi_get_undefined(env, &result);
1138 }
1139
1140 CommonCallbackRoutine(env, context, result);
1141 }
1142
Unmarshalling(napi_env env,napi_callback_info info)1143 napi_value SendablePixelMapNapi::Unmarshalling(napi_env env, napi_callback_info info)
1144 {
1145 std::unique_lock<std::shared_mutex> lock(mutex_);
1146 if (SendablePixelMapNapi::GetConstructor() == nullptr) {
1147 napi_value exports = nullptr;
1148 napi_create_object(env, &exports);
1149 SendablePixelMapNapi::Init(env, exports);
1150 }
1151 napi_value result = nullptr;
1152 napi_get_undefined(env, &result);
1153 int32_t refCount = 1;
1154 napi_status status;
1155 napi_value thisVar = nullptr;
1156 napi_value argValue[NUM_4] = {0};
1157 size_t argCount = NUM_4;
1158 IMAGE_LOGD("Unmarshalling IN");
1159 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1160 // we are static method!
1161 // thisVar is nullptr here
1162 if (!IMG_IS_OK(status)) {
1163 return ImageNapiUtils::ThrowExceptionError(
1164 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to napi_get_cb_info");
1165 }
1166 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1167
1168 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1169 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1170 }
1171
1172 NapiUnwrap(env, argValue[NUM_0], (void **)&napi_messageSequence_sendable, false);
1173 if (napi_messageSequence_sendable == nullptr) {
1174 return ImageNapiUtils::ThrowExceptionError(
1175 env, ERROR, "napi_messageSequence_sendable unwrapped is nullptr");
1176 }
1177
1178 if (asyncContext->callbackRef == nullptr) {
1179 napi_create_promise(env, &(asyncContext->deferred), &result);
1180 } else {
1181 napi_get_undefined(env, &result);
1182 }
1183
1184 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "Unmarshalling",
1185 UnmarshallingExec, UnmarshallingComplete, asyncContext, asyncContext->work);
1186
1187 if (!IMG_IS_OK(status)) {
1188 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
1189 return ImageNapiUtils::ThrowExceptionError(
1190 env, ERROR, "Fail to create async work");
1191 }
1192 return result;
1193 }
1194
ThrowExceptionError(napi_env env,const std::string & tag,const std::uint32_t & code,const std::string & info)1195 napi_value SendablePixelMapNapi::ThrowExceptionError(napi_env env,
1196 const std::string &tag, const std::uint32_t &code, const std::string &info)
1197 {
1198 auto errNode = ETS_API_ERROR_CODE.find(tag);
1199 if (errNode != ETS_API_ERROR_CODE.end() &&
1200 errNode->second.find(code) != errNode->second.end()) {
1201 return ImageNapiUtils::ThrowExceptionError(env, code, info);
1202 }
1203 return ImageNapiUtils::ThrowExceptionError(env, ERROR, "Operation failed");
1204 }
1205
CreateSendablPixelMapFromParcel(napi_env env,napi_callback_info info)1206 napi_value SendablePixelMapNapi::CreateSendablPixelMapFromParcel(napi_env env, napi_callback_info info)
1207 {
1208 if (SendablePixelMapNapi::GetConstructor() == nullptr) {
1209 napi_value exports = nullptr;
1210 napi_create_object(env, &exports);
1211 SendablePixelMapNapi::Init(env, exports);
1212 }
1213 napi_value result = nullptr;
1214 napi_get_undefined(env, &result);
1215 napi_status status;
1216 napi_value thisVar = nullptr;
1217 napi_value argValue[NUM_1] = {0};
1218 size_t argCount = NUM_1;
1219 IMAGE_LOGD("CreateSendablPixelMapFromParcel IN");
1220 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1221 if (!IMG_IS_OK(status) || argCount != NUM_1) {
1222 return SendablePixelMapNapi::ThrowExceptionError(env,
1223 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IMAGE_INVALID_PARAMETER, "Fail to napi_get_cb_info");
1224 }
1225 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1226 NapiUnwrap(env, argValue[NUM_0], (void **)&napi_messageSequence_sendable, false);
1227 IMG_NAPI_CHECK_RET_D(IMG_NOT_NULL(napi_messageSequence_sendable), result,
1228 IMAGE_LOGE("CreateSendablPixelMapFromParcel pixmapNapi unwrapped is nullptr"));
1229 auto messageParcel = napi_messageSequence_sendable->GetMessageParcel();
1230 if (messageParcel == nullptr) {
1231 return SendablePixelMapNapi::ThrowExceptionError(env,
1232 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IPC, "get pacel failed");
1233 }
1234 PIXEL_MAP_ERR error;
1235 auto pixelmap = PixelMap::Unmarshalling(*messageParcel, error);
1236 if (!IMG_NOT_NULL(pixelmap)) {
1237 return SendablePixelMapNapi::ThrowExceptionError(env,
1238 CREATE_PIXEL_MAP_FROM_PARCEL, error.errorCode, error.errorInfo);
1239 }
1240 std::shared_ptr<OHOS::Media::PixelMap> pixelPtr(pixelmap);
1241 napi_value constructor = nullptr;
1242 status = napi_get_reference_value(env, sConstructor_, &constructor);
1243 if (IMG_IS_OK(status)) {
1244 status = NewPixelNapiInstance(env, constructor, pixelPtr, result);
1245 }
1246 if (!IMG_IS_OK(status)) {
1247 IMAGE_LOGE("New instance could not be obtained");
1248 return SendablePixelMapNapi::ThrowExceptionError(env,
1249 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IMAGE_NAPI_ERROR, "New instance could not be obtained");
1250 }
1251 return result;
1252 }
1253
GetIsEditable(napi_env env,napi_callback_info info)1254 napi_value SendablePixelMapNapi::GetIsEditable(napi_env env, napi_callback_info info)
1255 {
1256 std::shared_lock<std::shared_mutex> lock(mutex_);
1257 napi_value result = nullptr;
1258 napi_get_undefined(env, &result);
1259
1260 napi_status status;
1261 napi_value thisVar = nullptr;
1262 size_t argCount = 0;
1263 IMAGE_LOGD("GetIsEditable IN");
1264
1265 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1266
1267 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1268
1269 SendablePixelMapNapi* pixelMapNapi = nullptr;
1270 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1271 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1272 IMAGE_LOGE("GetIsEditable fail to unwrap context"));
1273 IMG_NAPI_CHECK_RET_D(IMG_NOT_NULL(pixelMapNapi), result,
1274 IMAGE_LOGE("SendablePixelMapNapi unwrapped is nullptr"));
1275 IMG_NAPI_CHECK_RET_D(IMG_NOT_NULL(pixelMapNapi->nativePixelMap_), result,
1276 IMAGE_LOGE("nativePixelMap_ is nullptr"));
1277 bool isEditable = pixelMapNapi->nativePixelMap_->IsEditable();
1278
1279 napi_get_boolean(env, isEditable, &result);
1280
1281 return result;
1282 }
1283
GetIsStrideAlignment(napi_env env,napi_callback_info info)1284 napi_value SendablePixelMapNapi::GetIsStrideAlignment(napi_env env, napi_callback_info info)
1285 {
1286 std::shared_lock<std::shared_mutex> lock(mutex_);
1287 napi_value result = nullptr;
1288 napi_get_undefined(env, &result);
1289
1290 napi_status status;
1291 napi_value thisVar = nullptr;
1292 size_t argCount = 0;
1293 IMAGE_LOGD("GetIsStrideAlignment IN");
1294
1295 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1296
1297 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1298
1299 SendablePixelMapNapi* pixelMapNapi = nullptr;
1300 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1301 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi),
1302 result, IMAGE_LOGE("GetIsStrideAlignment fail to unwrap context"));
1303 IMG_NAPI_CHECK_RET_D(IMG_NOT_NULL(pixelMapNapi), result,
1304 IMAGE_LOGE("fail to unwrap context"));
1305 IMG_NAPI_CHECK_RET_D(IMG_NOT_NULL(pixelMapNapi->nativePixelMap_), result,
1306 IMAGE_LOGE("SendablePixelMapNapi->nativePixelMap_ is nullptr"));
1307 bool isDMA = pixelMapNapi->nativePixelMap_->IsStrideAlignment();
1308 napi_get_boolean(env, isDMA, &result);
1309 return result;
1310 }
1311
ReadPixelsToBuffer(napi_env env,napi_callback_info info)1312 napi_value SendablePixelMapNapi::ReadPixelsToBuffer(napi_env env, napi_callback_info info)
1313 {
1314 std::shared_lock<std::shared_mutex> lock(mutex_);
1315 ImageTrace imageTrace("SendablePixelMapNapi::ReadPixelsToBuffer");
1316 napi_value result = nullptr;
1317 napi_get_undefined(env, &result);
1318
1319 int32_t refCount = 1;
1320 napi_status status;
1321 napi_value thisVar = nullptr;
1322 napi_value argValue[NUM_2] = {0};
1323 size_t argCount = NUM_2;
1324
1325 IMAGE_LOGD("ReadPixelsToBuffer IN");
1326 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1327
1328 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1329
1330 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1331 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1332 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1333 nullptr, IMAGE_LOGE("ReadPixelsToBuffer fail to unwrap context"));
1334 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1335
1336 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1337 nullptr, IMAGE_LOGE("empty native pixelmap"));
1338
1339 status = napi_get_arraybuffer_info(env, argValue[NUM_0],
1340 &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
1341
1342 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
1343
1344 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1345 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1346 }
1347
1348 if (asyncContext->callbackRef == nullptr) {
1349 napi_create_promise(env, &(asyncContext->deferred), &result);
1350 } else {
1351 napi_get_undefined(env, &result);
1352 }
1353
1354 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1355 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . ReadPixelsToBuffer failed",
1356 ERR_RESOURCE_UNAVAILABLE),
1357 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
1358 result);
1359 IMG_CREATE_CREATE_ASYNC_WORK_WITH_QOS(env, status, "ReadPixelsToBuffer",
1360 [](napi_env env, void *data) {
1361 auto context = static_cast<PixelMapAsyncContext*>(data);
1362 context->status = context->rPixelMap->ReadPixels(
1363 context->colorsBufferSize, static_cast<uint8_t*>(context->colorsBuffer));
1364 }, EmptyResultComplete, asyncContext, asyncContext->work, napi_qos_user_initiated);
1365
1366 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
1367 IMAGE_LOGE("fail to create async work");
1368 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
1369 });
1370 return result;
1371 }
1372
ReadPixelsToBufferSync(napi_env env,napi_callback_info info)1373 napi_value SendablePixelMapNapi::ReadPixelsToBufferSync(napi_env env, napi_callback_info info)
1374 {
1375 std::shared_lock<std::shared_mutex> lock(mutex_);
1376 ImageTrace imageTrace("SendablePixelMapNapi::ReadPixelsToBufferSync");
1377 napi_value result = nullptr;
1378 napi_get_undefined(env, &result);
1379 napi_status napiStatus;
1380 uint32_t status = SUCCESS;
1381 napi_value thisVar = nullptr;
1382 size_t argCount = NUM_1;
1383 napi_value argValue[NUM_1] = {0};
1384 void* colorsBuffer = nullptr;
1385 size_t colorsBufferSize = 0;
1386
1387 IMAGE_LOGD("ReadPixelsToBuffeSync IN");
1388 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
1389 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1390 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
1391 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1392 "ReadPixelsToBuffeSync failed"),
1393 IMAGE_LOGE("ReadPixelsToBuffeSync failed, invalid parameter"));
1394
1395 napiStatus = napi_get_arraybuffer_info(env, argValue[NUM_0],
1396 &colorsBuffer, &colorsBufferSize);
1397 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
1398
1399 SendablePixelMapNapi* pixelMapNapi = nullptr;
1400 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1401 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1402 IMAGE_LOGE("ReadPixelsToBufferSync fail to unwrap context"));
1403 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1404 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1405 "Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"),
1406 IMAGE_LOGE("Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"));
1407
1408 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1409 status = pixelMapNapi->nativePixelMap_->ReadPixels(
1410 colorsBufferSize, static_cast<uint8_t*>(colorsBuffer));
1411 if (status != SUCCESS) {
1412 IMAGE_LOGE("ReadPixels failed");
1413 }
1414 } else {
1415 IMAGE_LOGE("Null native ref");
1416 }
1417 return result;
1418 }
1419
ReadPixels(napi_env env,napi_callback_info info)1420 napi_value SendablePixelMapNapi::ReadPixels(napi_env env, napi_callback_info info)
1421 {
1422 std::shared_lock<std::shared_mutex> lock(mutex_);
1423 napi_value result = nullptr;
1424 napi_get_undefined(env, &result);
1425
1426 int32_t refCount = 1;
1427 napi_status status;
1428 napi_value thisVar = nullptr;
1429 napi_value argValue[NUM_2] = {0};
1430 size_t argCount = NUM_2;
1431
1432 IMAGE_LOGD("ReadPixels IN");
1433 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1434
1435 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1436
1437 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1438 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1439 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1440 nullptr, IMAGE_LOGE("ReadPixels fail to unwrap context"));
1441
1442 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1443
1444 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1445 nullptr, IMAGE_LOGE("empty native pixelmap"));
1446
1447 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
1448 nullptr, IMAGE_LOGE("fail to parse position area"));
1449
1450 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1451 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1452 }
1453
1454 if (asyncContext->callbackRef == nullptr) {
1455 napi_create_promise(env, &(asyncContext->deferred), &result);
1456 } else {
1457 napi_get_undefined(env, &result);
1458 }
1459
1460 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1461 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . ReadPixels failed",
1462 ERR_RESOURCE_UNAVAILABLE),
1463 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
1464 result);
1465 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixels",
1466 [](napi_env env, void *data) {
1467 auto context = static_cast<PixelMapAsyncContext*>(data);
1468 auto area = context->area;
1469 context->status = context->rPixelMap->ReadPixels(
1470 area.size, area.offset, area.stride, area.region, static_cast<uint8_t*>(area.pixels));
1471 }, EmptyResultComplete, asyncContext, asyncContext->work);
1472
1473 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
1474 IMAGE_LOGE("fail to create async work");
1475 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
1476 });
1477 return result;
1478 }
1479
ReadPixelsSync(napi_env env,napi_callback_info info)1480 napi_value SendablePixelMapNapi::ReadPixelsSync(napi_env env, napi_callback_info info)
1481 {
1482 std::shared_lock<std::shared_mutex> lock(mutex_);
1483 napi_value result = nullptr;
1484 napi_get_undefined(env, &result);
1485
1486 napi_status status;
1487 napi_value thisVar = nullptr;
1488 napi_value argValue[NUM_1] = {0};
1489 size_t argCount = NUM_1;
1490 PositionArea area;
1491 IMAGE_LOGD("ReadPixelsSync IN");
1492 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1493
1494 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1495 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
1496 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1497 "Invalid args count"),
1498 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
1499 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &area),
1500 nullptr, IMAGE_LOGE("fail to parse position area"));
1501
1502 SendablePixelMapNapi* pixelMapNapi = nullptr;
1503 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1504 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1505 IMAGE_LOGE("ReadPixelsSync fail to unwrap context"));
1506 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1507 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1508 "Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"),
1509 IMAGE_LOGE("Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"));
1510
1511 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi->nativePixelMap_),
1512 nullptr, IMAGE_LOGE("empty native pixelmap"));
1513
1514 auto nativeStatus = pixelMapNapi->nativePixelMap_->ReadPixels(
1515 area.size, area.offset, area.stride, area.region, static_cast<uint8_t*>(area.pixels));
1516
1517 IMG_NAPI_CHECK_RET_D(nativeStatus == SUCCESS,
1518 nullptr, IMAGE_LOGE("fail to read pixels"));
1519 return result;
1520 }
1521
WritePixels(napi_env env,napi_callback_info info)1522 napi_value SendablePixelMapNapi::WritePixels(napi_env env, napi_callback_info info)
1523 {
1524 std::unique_lock<std::shared_mutex> lock(mutex_);
1525 napi_value result = nullptr;
1526 napi_get_undefined(env, &result);
1527
1528 int32_t refCount = 1;
1529 napi_status status;
1530 napi_value thisVar = nullptr;
1531 napi_value argValue[NUM_2] = {0};
1532 size_t argCount = NUM_2;
1533
1534 IMAGE_LOGD("WritePixels IN");
1535 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1536
1537 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1538
1539 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1540 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1541 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1542 nullptr, IMAGE_LOGE("WritePixels fail to unwrap context"));
1543 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1544
1545 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1546 nullptr, IMAGE_LOGE("empty native pixelmap"));
1547
1548 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
1549 nullptr, IMAGE_LOGE("fail to parse position area"));
1550
1551 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1552 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1553 }
1554
1555 if (asyncContext->callbackRef == nullptr) {
1556 napi_create_promise(env, &(asyncContext->deferred), &result);
1557 } else {
1558 napi_get_undefined(env, &result);
1559 }
1560 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1561 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . WritePixels failed",
1562 ERR_RESOURCE_UNAVAILABLE),
1563 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
1564 result);
1565 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WritePixels",
1566 [](napi_env env, void *data) {
1567 auto context = static_cast<PixelMapAsyncContext*>(data);
1568 auto area = context->area;
1569 context->status = context->rPixelMap->WritePixels(
1570 static_cast<uint8_t*>(area.pixels), area.size, area.offset, area.stride, area.region);
1571 }, EmptyResultComplete, asyncContext, asyncContext->work);
1572
1573 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
1574 IMAGE_LOGE("fail to create async work");
1575 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
1576 });
1577 return result;
1578 }
1579
WritePixelsSync(napi_env env,napi_callback_info info)1580 napi_value SendablePixelMapNapi::WritePixelsSync(napi_env env, napi_callback_info info)
1581 {
1582 std::unique_lock<std::shared_mutex> lock(mutex_);
1583 napi_value result = nullptr;
1584 napi_get_undefined(env, &result);
1585 napi_status napiStatus;
1586 uint32_t status = SUCCESS;
1587 napi_value thisVar = nullptr;
1588 size_t argCount = NUM_1;
1589 napi_value argValue[NUM_1] = {0};
1590 PositionArea area;
1591 IMAGE_LOGD("WritePixelsSyncIN");
1592 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
1593 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to arg info"));
1594 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
1595 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1596 "Invalid args count"),
1597 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
1598 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &area),
1599 nullptr, IMAGE_LOGE("fail to parse position area"));
1600
1601 SendablePixelMapNapi* pixelMapNapi = nullptr;
1602 napiStatus = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1603 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result,
1604 IMAGE_LOGE("WritePixelsSync fail to unwrap context"));
1605 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1606 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1607 "Pixelmap has crossed threads . WritePixelsSync failed"),
1608 IMAGE_LOGE("Pixelmap has crossed threads . WritePixelsSync failed"));
1609
1610 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1611 status = pixelMapNapi->nativePixelMap_->WritePixels(
1612 static_cast<uint8_t*>(area.pixels), area.size, area.offset, area.stride, area.region);
1613 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr,
1614 IMAGE_LOGE("fail to write pixels"));
1615 } else {
1616 IMAGE_LOGE("Null native ref");
1617 }
1618 return result;
1619 }
1620
WriteBufferToPixels(napi_env env,napi_callback_info info)1621 napi_value SendablePixelMapNapi::WriteBufferToPixels(napi_env env, napi_callback_info info)
1622 {
1623 std::unique_lock<std::shared_mutex> lock(mutex_);
1624 ImageTrace imageTrace("SendablePixelMapNapi::WriteBufferToPixels");
1625 napi_value result = nullptr;
1626 napi_get_undefined(env, &result);
1627
1628 int32_t refCount = 1;
1629 napi_status status;
1630 napi_value thisVar = nullptr;
1631 napi_value argValue[NUM_2] = {0};
1632 size_t argCount = NUM_2;
1633
1634 IMAGE_LOGD("WriteBufferToPixels IN");
1635 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1636
1637 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1638
1639 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1640 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1641 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1642 nullptr, IMAGE_LOGE("WriteBufferToPixels fail to unwrap context"));
1643
1644 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1645
1646 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1647 nullptr, IMAGE_LOGE("empty native pixelmap"));
1648 status = napi_get_arraybuffer_info(env, argValue[NUM_0],
1649 &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
1650
1651 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1652 nullptr, IMAGE_LOGE("fail to get buffer info"));
1653
1654 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1655 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1656 }
1657
1658 if (asyncContext->callbackRef == nullptr) {
1659 napi_create_promise(env, &(asyncContext->deferred), &result);
1660 } else {
1661 napi_get_undefined(env, &result);
1662 }
1663 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1664 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . WriteBufferToPixels failed",
1665 ERR_RESOURCE_UNAVAILABLE),
1666 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
1667 result);
1668 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WriteBufferToPixels",
1669 [](napi_env env, void *data) {
1670 auto context = static_cast<PixelMapAsyncContext*>(data);
1671 context->status = context->rPixelMap->WritePixels(static_cast<uint8_t*>(context->colorsBuffer),
1672 context->colorsBufferSize);
1673 }, EmptyResultComplete, asyncContext, asyncContext->work);
1674
1675 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
1676 IMAGE_LOGE("fail to create async work");
1677 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
1678 });
1679 return result;
1680 }
1681
WriteBufferToPixelsSync(napi_env env,napi_callback_info info)1682 napi_value SendablePixelMapNapi::WriteBufferToPixelsSync(napi_env env, napi_callback_info info)
1683 {
1684 std::unique_lock<std::shared_mutex> lock(mutex_);
1685 ImageTrace imageTrace("SendablePixelMapNapi::WriteBufferToPixelsSync");
1686 napi_value result = nullptr;
1687 napi_get_undefined(env, &result);
1688 napi_status napiStatus;
1689 uint32_t status = SUCCESS;
1690 napi_value thisVar = nullptr;
1691 size_t argCount = NUM_1;
1692 napi_value argValue[NUM_1] = {0};
1693 void* colorsBuffer = nullptr;
1694 size_t colorsBufferSize = 0;
1695
1696 IMAGE_LOGD("WriteBufferToPixelsSync IN");
1697 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
1698 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1699 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
1700 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1701 "WriteBufferToPixelsSync failed"),
1702 IMAGE_LOGE("WriteBufferToPixelsSync failed, invalid parameter"));
1703
1704 napiStatus = napi_get_arraybuffer_info(env, argValue[NUM_0],
1705 &colorsBuffer, &colorsBufferSize);
1706 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
1707
1708 SendablePixelMapNapi* pixelMapNapi = nullptr;
1709 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1710 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1711 IMAGE_LOGE("WriteBufferToPixelsSync fail to unwrap context"));
1712 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1713 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1714 "Pixelmap has crossed threads . WriteBufferToPixelsSync failed"),
1715 IMAGE_LOGE("Pixelmap has crossed threads . WriteBufferToPixelsSync failed"));
1716
1717 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1718 status = pixelMapNapi->nativePixelMap_->WritePixels(
1719 static_cast<uint8_t*>(colorsBuffer), colorsBufferSize);
1720 if (status != SUCCESS) {
1721 IMAGE_LOGE("WritePixels failed");
1722 }
1723 } else {
1724 IMAGE_LOGE("Null native ref");
1725 }
1726 return result;
1727 }
1728
STATIC_NAPI_VALUE_FUNC(GetImageInfo)1729 STATIC_NAPI_VALUE_FUNC(GetImageInfo)
1730 {
1731 IMAGE_LOGD("[PixelMap]GetImageInfoNapiValue IN");
1732 napi_value result = nullptr;
1733 napi_create_object(env, &result);
1734 auto imageInfo = static_cast<ImageInfo*>(data);
1735 auto rPixelMap = static_cast<PixelMap*>(ptr);
1736 napi_value size = nullptr;
1737 napi_create_object(env, &size);
1738 napi_value sizeWith = nullptr;
1739 napi_create_int32(env, imageInfo->size.width, &sizeWith);
1740 napi_set_named_property(env, size, "width", sizeWith);
1741 napi_value sizeHeight = nullptr;
1742 napi_create_int32(env, imageInfo->size.height, &sizeHeight);
1743 napi_set_named_property(env, size, "height", sizeHeight);
1744 napi_set_named_property(env, result, "size", size);
1745 napi_value pixelFormatValue = nullptr;
1746 napi_create_int32(env, static_cast<int32_t>(imageInfo->pixelFormat), &pixelFormatValue);
1747 napi_set_named_property(env, result, "pixelFormat", pixelFormatValue);
1748 napi_value colorSpaceValue = nullptr;
1749 napi_create_int32(env, static_cast<int32_t>(imageInfo->colorSpace), &colorSpaceValue);
1750 napi_set_named_property(env, result, "colorSpace", colorSpaceValue);
1751 napi_value alphaTypeValue = nullptr;
1752 napi_create_int32(env, static_cast<int32_t>(imageInfo->alphaType), &alphaTypeValue);
1753 napi_set_named_property(env, result, "alphaType", alphaTypeValue);
1754 napi_value densityValue = nullptr;
1755 napi_create_int32(env, static_cast<int32_t>(imageInfo->baseDensity), &densityValue);
1756 napi_set_named_property(env, result, "density", densityValue);
1757 napi_value strideValue = nullptr;
1758 napi_create_int32(env, static_cast<int32_t>(rPixelMap->GetRowStride()), &strideValue);
1759 napi_set_named_property(env, result, "stride", strideValue);
1760 napi_value encodedFormatValue = nullptr;
1761 napi_create_string_utf8(env, imageInfo->encodedFormat.c_str(),
1762 imageInfo->encodedFormat.length(), &encodedFormatValue);
1763 napi_set_named_property(env, result, "mimeType", encodedFormatValue);
1764 napi_value isHdrValue = nullptr;
1765 napi_get_boolean(env, rPixelMap->IsHdr(), &isHdrValue);
1766 napi_set_named_property(env, result, "isHdr", isHdrValue);
1767 return result;
1768 }
1769
STATIC_COMPLETE_FUNC(GetImageInfo)1770 STATIC_COMPLETE_FUNC(GetImageInfo)
1771 {
1772 IMAGE_LOGD("[PixelMap]GetImageInfoComplete IN");
1773 auto context = static_cast<PixelMapAsyncContext*>(data);
1774 napi_value result = GetImageInfoNapiValue(env, &(context->imageInfo), context->rPixelMap.get());
1775
1776 if (!IMG_IS_OK(status)) {
1777 context->status = ERROR;
1778 IMAGE_LOGE("napi_create_int32 failed!");
1779 napi_get_undefined(env, &result);
1780 } else {
1781 context->status = SUCCESS;
1782 }
1783 IMAGE_LOGD("[PixelMap]GetImageInfoComplete OUT");
1784 CommonCallbackRoutine(env, context, result);
1785 }
GetImageInfo(napi_env env,napi_callback_info info)1786 napi_value SendablePixelMapNapi::GetImageInfo(napi_env env, napi_callback_info info)
1787 {
1788 std::shared_lock<std::shared_mutex> lock(mutex_);
1789 napi_value result = nullptr;
1790 napi_get_undefined(env, &result);
1791 int32_t refCount = 1;
1792 napi_status status;
1793 napi_value thisVar = nullptr;
1794 napi_value argValue[NUM_1] = {0};
1795 size_t argCount = 1;
1796 IMAGE_LOGD("GetImageInfo IN");
1797 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1798 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1799 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1800 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1801 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1802 nullptr, IMAGE_LOGE("GetImageInfo fail to unwrap context"));
1803 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1804 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1805 nullptr, IMAGE_LOGE("empty native pixelmap"));
1806 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1807 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1808 }
1809 if (asyncContext->callbackRef == nullptr) {
1810 napi_create_promise(env, &(asyncContext->deferred), &result);
1811 } else {
1812 napi_get_undefined(env, &result);
1813 }
1814 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1815 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . GetImageInfo failed",
1816 ERR_RESOURCE_UNAVAILABLE),
1817 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
1818 result);
1819 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfo",
1820 [](napi_env env, void *data) {
1821 auto context = static_cast<PixelMapAsyncContext*>(data);
1822 context->rPixelMap->GetImageInfo(context->imageInfo);
1823 context->status = SUCCESS;
1824 }, GetImageInfoComplete, asyncContext, asyncContext->work);
1825 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
1826 IMAGE_LOGE("fail to create async work");
1827 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
1828 });
1829 return result;
1830 }
1831
GetImageInfoSync(napi_env env,napi_callback_info info)1832 napi_value SendablePixelMapNapi::GetImageInfoSync(napi_env env, napi_callback_info info)
1833 {
1834 std::shared_lock<std::shared_mutex> lock(mutex_);
1835 napi_value result = nullptr;
1836 napi_get_undefined(env, &result);
1837 napi_status napiStatus;
1838 napi_value thisVar = nullptr;
1839 size_t argCount = NUM_0;
1840
1841 IMAGE_LOGD("GetImageInfoSync IN");
1842 IMG_JS_ARGS(env, info, napiStatus, argCount, nullptr, thisVar);
1843 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to arg info"));
1844
1845 SendablePixelMapNapi* pixelMapNapi = nullptr;
1846 napiStatus = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1847 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result,
1848 IMAGE_LOGE("GetImageInfoSync fail to unwrap context"));
1849 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1850 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1851 "Pixelmap has crossed threads . GetImageInfoSync failed"),
1852 IMAGE_LOGE("Pixelmap has crossed threads . GetImageInfoSync failed"));
1853
1854 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1855 ImageInfo imageinfo;
1856 pixelMapNapi->nativePixelMap_->GetImageInfo(imageinfo);
1857 result = GetImageInfoNapiValue(env, &imageinfo, pixelMapNapi->nativePixelMap_.get());
1858 } else {
1859 IMAGE_LOGE("native pixelmap is nullptr!");
1860 }
1861 return result;
1862 }
1863
GetBytesNumberPerRow(napi_env env,napi_callback_info info)1864 napi_value SendablePixelMapNapi::GetBytesNumberPerRow(napi_env env, napi_callback_info info)
1865 {
1866 std::shared_lock<std::shared_mutex> lock(mutex_);
1867 ImageTrace imageTrace("SendablePixelMapNapi::GetBytesNumberPerRow");
1868 napi_value result = nullptr;
1869 napi_get_undefined(env, &result);
1870
1871 napi_status status;
1872 napi_value thisVar = nullptr;
1873 size_t argCount = 0;
1874
1875 IMAGE_LOGD("GetBytesNumberPerRow IN");
1876 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1877
1878 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1879
1880 SendablePixelMapNapi* pixelMapNapi = nullptr;
1881 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1882 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1883 IMAGE_LOGE("fail to unwrap context"));
1884 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1885 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1886 "Pixelmap has crossed threads . GetBytesNumberPerRow failed"),
1887 IMAGE_LOGE("Pixelmap has crossed threads . GetBytesNumberPerRow failed"));
1888
1889 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1890 uint32_t rowBytes = pixelMapNapi->nativePixelMap_->GetRowBytes();
1891 status = napi_create_int32(env, rowBytes, &result);
1892 if (!IMG_IS_OK(status)) {
1893 IMAGE_LOGE("napi_create_int32 failed!");
1894 }
1895 } else {
1896 IMAGE_LOGE("native pixelmap is nullptr!");
1897 }
1898 return result;
1899 }
1900
GetPixelBytesNumber(napi_env env,napi_callback_info info)1901 napi_value SendablePixelMapNapi::GetPixelBytesNumber(napi_env env, napi_callback_info info)
1902 {
1903 std::shared_lock<std::shared_mutex> lock(mutex_);
1904 ImageTrace imageTrace("SendablePixelMapNapi::GetPixelBytesNumber");
1905 napi_value result = nullptr;
1906 napi_get_undefined(env, &result);
1907
1908 napi_status status;
1909 napi_value thisVar = nullptr;
1910 size_t argCount = 0;
1911
1912 IMAGE_LOGD("GetPixelBytesNumber IN");
1913 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1914
1915 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1916
1917 SendablePixelMapNapi* pixelMapNapi = nullptr;
1918 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1919 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1920 IMAGE_LOGE("GetPixelBytesNumber fail to unwrap context"));
1921 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1922 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1923 "Pixelmap has crossed threads . GetPixelBytesNumber failed"),
1924 IMAGE_LOGE("Pixelmap has crossed threads . GetPixelBytesNumber failed"));
1925
1926 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1927 uint32_t byteCount = pixelMapNapi->nativePixelMap_->GetByteCount();
1928 status = napi_create_int32(env, byteCount, &result);
1929 if (!IMG_IS_OK(status)) {
1930 IMAGE_LOGE("napi_create_int32 failed!");
1931 }
1932 } else {
1933 IMAGE_LOGE("native pixelmap is nullptr!");
1934 }
1935 return result;
1936 }
1937
IsSupportAlpha(napi_env env,napi_callback_info info)1938 napi_value SendablePixelMapNapi::IsSupportAlpha(napi_env env, napi_callback_info info)
1939 {
1940 std::shared_lock<std::shared_mutex> lock(mutex_);
1941 napi_value result = nullptr;
1942 napi_get_undefined(env, &result);
1943
1944 napi_status status;
1945 napi_value thisVar = nullptr;
1946 size_t argCount = NUM_0;
1947
1948 IMAGE_LOGD("IsSupportAlpha IN");
1949 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1950
1951 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1952
1953 SendablePixelMapNapi* pixelMapNapi = nullptr;
1954 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1955 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1956 IMAGE_LOGE("IsSupportAlpha fail to unwrap context"));
1957 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1958 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1959 "Pixelmap has crossed threads . IsSupportAlpha failed"),
1960 IMAGE_LOGE("Pixelmap has crossed threads . IsSupportAlpha failed"));
1961
1962 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1963 AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
1964 bool isSupportAlpha = !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
1965 status = napi_get_boolean(env, isSupportAlpha, &result);
1966 if (!IMG_IS_OK(status)) {
1967 IMAGE_LOGE("napi_create_bool failed!");
1968 }
1969 } else {
1970 IMAGE_LOGE("native pixelmap is nullptr!");
1971 }
1972 return result;
1973 }
1974
SetAlphaAble(napi_env env,napi_callback_info info)1975 napi_value SendablePixelMapNapi::SetAlphaAble(napi_env env, napi_callback_info info)
1976 {
1977 std::unique_lock<std::shared_mutex> lock(mutex_);
1978 napi_value result = nullptr;
1979 napi_get_undefined(env, &result);
1980
1981 napi_status status;
1982 napi_value thisVar = nullptr;
1983 napi_value argValue[NUM_1] = {0};
1984 size_t argCount = NUM_1;
1985 bool isAlphaAble = false;
1986
1987 IMAGE_LOGD("SetAlphaAble IN");
1988 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1989
1990 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1991 NAPI_ASSERT(env, argCount > NUM_0, "Invalid input");
1992 NAPI_ASSERT(env, ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_boolean, "Invalid input type");
1993 NAPI_ASSERT(env, napi_get_value_bool(env, argValue[NUM_0], &isAlphaAble) == napi_ok, "Parse input error");
1994
1995 SendablePixelMapNapi* pixelMapNapi = nullptr;
1996 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1997 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
1998 IMAGE_LOGE("SetAlphaAble fail to unwrap context"));
1999 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2000 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2001 "Pixelmap has crossed threads . SetAlphaAble failed"),
2002 IMAGE_LOGE("Pixelmap has crossed threads . SetAlphaAble failed"));
2003 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2004 AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
2005 if (isAlphaAble && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
2006 pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
2007 } else if ((!isAlphaAble) && !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
2008 pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
2009 }
2010 } else {
2011 IMAGE_LOGE("native pixelmap is nullptr!");
2012 }
2013 return result;
2014 }
2015
CreateAlphaPixelmapComplete(napi_env env,napi_status status,void * data)2016 static void CreateAlphaPixelmapComplete(napi_env env, napi_status status, void *data)
2017 {
2018 napi_value result = nullptr;
2019 napi_get_undefined(env, &result);
2020 auto context = static_cast<PixelMapAsyncContext*>(data);
2021
2022 if (context->alphaMap != nullptr) {
2023 result = SendablePixelMapNapi::CreateSendablePixelMap(env, context->alphaMap);
2024 context->status = SUCCESS;
2025 } else {
2026 context->status = ERROR;
2027 }
2028 CommonCallbackRoutine(env, context, result);
2029 }
2030
CreateAlphaPixelmap(napi_env env,napi_callback_info info)2031 napi_value SendablePixelMapNapi::CreateAlphaPixelmap(napi_env env, napi_callback_info info)
2032 {
2033 std::unique_lock<std::shared_mutex> lock(mutex_);
2034 napi_value result = nullptr;
2035 napi_get_undefined(env, &result);
2036 int32_t refCount = 1;
2037 napi_status status;
2038 napi_value thisVar = nullptr;
2039 napi_value argValue[NUM_1] = {0};
2040 size_t argCount = 1;
2041 IMAGE_LOGD("CreateAlphaPixelmap IN");
2042 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2043 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
2044 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
2045 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
2046 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
2047 nullptr, IMAGE_LOGE("CreateAlphaPixelmap fail to unwrap context"));
2048 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
2049 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
2050 nullptr, IMAGE_LOGE("empty native pixelmap"));
2051 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
2052 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
2053 }
2054 if (asyncContext->callbackRef == nullptr) {
2055 napi_create_promise(env, &(asyncContext->deferred), &result);
2056 } else {
2057 napi_get_undefined(env, &result);
2058 }
2059 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
2060 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . CreateAlphaPixelmap failed",
2061 ERR_RESOURCE_UNAVAILABLE),
2062 NapiSendEvent(env, asyncContext.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
2063 result);
2064 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateAlphaPixelmap",
2065 [](napi_env env, void *data) {
2066 auto context = static_cast<PixelMapAsyncContext*>(data);
2067 InitializationOptions opts;
2068 opts.pixelFormat = PixelFormat::ALPHA_8;
2069 auto tmpPixelMap = PixelMap::Create(*(context->rPixelMap), opts);
2070 context->alphaMap = std::move(tmpPixelMap);
2071 context->status = SUCCESS;
2072 }, CreateAlphaPixelmapComplete, asyncContext, asyncContext->work);
2073 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, {
2074 IMAGE_LOGE("fail to create async work");
2075 NAPI_CHECK_AND_DELETE_REF(env, asyncContext->callbackRef);
2076 });
2077 return result;
2078 }
2079
CreateAlphaPixelmapSync(napi_env env,napi_callback_info info)2080 napi_value SendablePixelMapNapi::CreateAlphaPixelmapSync(napi_env env, napi_callback_info info)
2081 {
2082 std::unique_lock<std::shared_mutex> lock(mutex_);
2083 napi_value result = nullptr;
2084 napi_get_undefined(env, &result);
2085 napi_status napiStatus;
2086 napi_value thisVar = nullptr;
2087 size_t argCount = NUM_0;
2088
2089 IMAGE_LOGD("CreateAlphaPixelmapSync IN");
2090 IMG_JS_ARGS(env, info, napiStatus, argCount, nullptr, thisVar);
2091 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2092 IMG_NAPI_CHECK_RET_D(argCount == NUM_0,
2093 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2094 "CreateAlphaPixelmapSync failed"),
2095 IMAGE_LOGE("CreateAlphaPixelmapSync failed, invalid parameter"));
2096
2097 SendablePixelMapNapi* pixelMapNapi = nullptr;
2098 napiStatus = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2099 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result,
2100 IMAGE_LOGE("CreateAlphaPixelmapSync fail to unwrap context"));
2101 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2102 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2103 "Pixelmap has crossed threads . CreateAlphaPixelmapSync failed"),
2104 IMAGE_LOGE("Pixelmap has crossed threads . CreateAlphaPixelmapSync failed"));
2105
2106 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2107 InitializationOptions opts;
2108 opts.pixelFormat = PixelFormat::ALPHA_8;
2109 auto tmpPixelMap = PixelMap::Create(*(pixelMapNapi->nativePixelMap_), opts);
2110 result = SendablePixelMapNapi::CreateSendablePixelMap(env, std::move(tmpPixelMap));
2111 } else {
2112 IMAGE_LOGE("Null native ref");
2113 }
2114 return result;
2115 }
2116
GetDensity(napi_env env,napi_callback_info info)2117 napi_value SendablePixelMapNapi::GetDensity(napi_env env, napi_callback_info info)
2118 {
2119 std::shared_lock<std::shared_mutex> lock(mutex_);
2120 napi_value result = nullptr;
2121 napi_get_undefined(env, &result);
2122
2123 napi_status status;
2124 napi_value thisVar = nullptr;
2125 size_t argCount = 0;
2126
2127 IMAGE_LOGD("GetDensity IN");
2128 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
2129
2130 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2131
2132 SendablePixelMapNapi* pixelMapNapi = nullptr;
2133 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2134 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
2135 IMAGE_LOGE("GetDensity fail to unwrap context"));
2136 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2137 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2138 "Pixelmap has crossed threads . GetDensity failed"),
2139 IMAGE_LOGE("Pixelmap has crossed threads . GetDensity failed"));
2140
2141 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2142 uint32_t baseDensity = pixelMapNapi->nativePixelMap_->GetBaseDensity();
2143 status = napi_create_int32(env, baseDensity, &result);
2144 if (!IMG_IS_OK(status)) {
2145 IMAGE_LOGE("napi_create_int32 failed!");
2146 }
2147 } else {
2148 IMAGE_LOGE("native pixelmap is nullptr!");
2149 }
2150 return result;
2151 }
2152
SetDensity(napi_env env,napi_callback_info info)2153 napi_value SendablePixelMapNapi::SetDensity(napi_env env, napi_callback_info info)
2154 {
2155 std::unique_lock<std::shared_mutex> lock(mutex_);
2156 napi_value result = nullptr;
2157 napi_get_undefined(env, &result);
2158
2159 napi_status status;
2160 napi_value thisVar = nullptr;
2161 napi_value argValue[NUM_1] = {0};
2162 size_t argCount = NUM_1;
2163 uint32_t density = 0;
2164
2165 IMAGE_LOGD("SetDensity IN");
2166 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2167 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2168
2169 NAPI_ASSERT(env,
2170 (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number),
2171 "Density input mismatch");
2172 NAPI_ASSERT(env, napi_get_value_uint32(env, argValue[NUM_0], &density) == napi_ok, "Could not parse density");
2173
2174 SendablePixelMapNapi* pixelMapNapi = nullptr;
2175 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2176 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
2177 IMAGE_LOGE("SetDensity fail to unwrap context"));
2178 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2179 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2180 "Pixelmap has crossed threads . SetDensity failed"),
2181 IMAGE_LOGE("Pixelmap has crossed threads . SetDensity failed"));
2182 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2183 ImageInfo imageinfo;
2184 pixelMapNapi->nativePixelMap_->GetImageInfo(imageinfo);
2185 imageinfo.baseDensity = density;
2186 pixelMapNapi->nativePixelMap_->SetImageInfo(imageinfo, true);
2187 } else {
2188 IMAGE_LOGE("native pixelmap is nullptr!");
2189 }
2190 return result;
2191 }
2192
Release(napi_env env,napi_callback_info info)2193 napi_value SendablePixelMapNapi::Release(napi_env env, napi_callback_info info)
2194 {
2195 std::unique_lock<std::shared_mutex> lock(mutex_);
2196 napi_value result = nullptr;
2197 napi_get_undefined(env, &result);
2198
2199 int32_t refCount = 1;
2200 napi_status status;
2201 napi_value thisVar = nullptr;
2202 napi_value argValue[1] = {0};
2203 size_t argCount = 1;
2204
2205 IMAGE_LOGD("Release IN");
2206 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2207
2208 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
2209
2210 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
2211 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
2212 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
2213 nullptr, IMAGE_LOGE("Release fail to unwrap context"));
2214
2215 if (argCount == 1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
2216 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
2217 }
2218
2219 if (asyncContext->callbackRef == nullptr) {
2220 napi_create_promise(env, &(asyncContext->deferred), &result);
2221 } else {
2222 napi_get_undefined(env, &result);
2223 }
2224 if (asyncContext->nConstructor->IsLockPixelMap()) {
2225 asyncContext->status = ERROR;
2226 } else {
2227 if (asyncContext->nConstructor->nativePixelMap_ != nullptr) {
2228 IMAGE_LOGD("Release in napi_id:%{public}d, id:%{public}d",
2229 asyncContext->nConstructor->GetUniqueId(),
2230 asyncContext->nConstructor->nativePixelMap_->GetUniqueId());
2231 asyncContext->nConstructor->nativePixelMap_.reset();
2232 }
2233 asyncContext->status = SUCCESS;
2234 }
2235 NapiSendEvent(env, asyncContext.release(), napi_eprio_high);
2236 return result;
2237 }
2238
2239 struct NapiValues {
2240 napi_status status;
2241 napi_value thisVar = nullptr;
2242 napi_value result = nullptr;
2243 napi_value* argv = nullptr;
2244 size_t argc;
2245 int32_t refCount = 1;
2246 std::unique_ptr<PixelMapAsyncContext> context;
2247 };
2248
prepareNapiEnv(napi_env env,napi_callback_info info,struct NapiValues * nVal)2249 static bool prepareNapiEnv(napi_env env, napi_callback_info info, struct NapiValues* nVal)
2250 {
2251 napi_get_undefined(env, &(nVal->result));
2252 nVal->status = napi_get_cb_info(env, info, &(nVal->argc), nVal->argv, &(nVal->thisVar), nullptr);
2253 if (nVal->status != napi_ok) {
2254 IMAGE_LOGE("fail to napi_get_cb_info");
2255 return false;
2256 }
2257 nVal->context = std::make_unique<PixelMapAsyncContext>();
2258 nVal->status = NapiUnwrap(env, nVal->thisVar, reinterpret_cast<void**>(&(nVal->context->nConstructor)));
2259 if (nVal->status != napi_ok || nVal->context->nConstructor == nullptr) {
2260 IMAGE_LOGE("fail to unwrap context");
2261 return false;
2262 }
2263 nVal->context->status = SUCCESS;
2264 return true;
2265 }
2266
SetAlphaExec(napi_env env,PixelMapAsyncContext * context)2267 static void SetAlphaExec(napi_env env, PixelMapAsyncContext* context)
2268 {
2269 if (context == nullptr) {
2270 IMAGE_LOGE("Null context");
2271 return;
2272 }
2273 if (context->status == SUCCESS) {
2274 if (context->rPixelMap != nullptr) {
2275 context->status = context->rPixelMap->SetAlpha(
2276 static_cast<float>(context->alpha));
2277 } else {
2278 IMAGE_LOGE("Null native ref");
2279 context->status = ERR_IMAGE_INIT_ABNORMAL;
2280 }
2281 } else {
2282 IMAGE_LOGD("Scale has failed. do nothing");
2283 }
2284 }
2285
SetAlpha(napi_env env,napi_callback_info info)2286 napi_value SendablePixelMapNapi::SetAlpha(napi_env env, napi_callback_info info)
2287 {
2288 std::unique_lock<std::shared_mutex> lock(mutex_);
2289 NapiValues nVal;
2290 nVal.argc = NUM_2;
2291 napi_value argValue[NUM_2] = {0};
2292 nVal.argv = argValue;
2293
2294 IMAGE_LOGD("SetAlpha IN");
2295 if (!prepareNapiEnv(env, info, &nVal)) {
2296 return nVal.result;
2297 }
2298 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2299
2300 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
2301 IMAGE_LOGE("Invalid args count %{public}zu", nVal.argc);
2302 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2303 } else {
2304 if (napi_ok !=
2305 napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->alpha))) {
2306 IMAGE_LOGE("Arg 0 type mismatch");
2307 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2308 }
2309 }
2310 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2311 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2312 }
2313
2314 if (nVal.context->callbackRef == nullptr) {
2315 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2316 }
2317 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2318 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . SetAlpha failed",
2319 ERR_RESOURCE_UNAVAILABLE),
2320 NapiSendEvent(env, nVal.context.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
2321 nVal.result);
2322 napi_value _resource = nullptr;
2323 napi_create_string_utf8(env, "SetAlpha", NAPI_AUTO_LENGTH, &_resource);
2324 nVal.status = napi_create_async_work(env, nullptr, _resource,
2325 [](napi_env env, void *data) {
2326 auto context = static_cast<PixelMapAsyncContext*>(data);
2327 SetAlphaExec(env, context);
2328 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2329
2330 if (nVal.status == napi_ok) {
2331 nVal.status = napi_queue_async_work(env, nVal.context->work);
2332 if (nVal.status == napi_ok) {
2333 nVal.context.release();
2334 } else {
2335 NAPI_CHECK_AND_DELETE_REF(env, nVal.context->callbackRef);
2336 }
2337 }
2338 return nVal.result;
2339 }
2340
SetAlphaSync(napi_env env,napi_callback_info info)2341 napi_value SendablePixelMapNapi::SetAlphaSync(napi_env env, napi_callback_info info)
2342 {
2343 std::unique_lock<std::shared_mutex> lock(mutex_);
2344 napi_value result = nullptr;
2345 napi_get_undefined(env, &result);
2346 napi_status napiStatus;
2347 uint32_t status = SUCCESS;
2348 napi_value thisVar = nullptr;
2349 size_t argCount = NUM_1;
2350 napi_value argValue[NUM_1] = {0};
2351 double alpha = 0;
2352
2353 IMAGE_LOGD("SetAlphaSync IN");
2354 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2355 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2356 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
2357 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2358 "SetAlphaSync failed"),
2359 IMAGE_LOGE("SetAlphaSync failed, invalid parameter"));
2360 napiStatus= napi_get_value_double(env, argValue[NUM_0], &alpha);
2361
2362 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
2363
2364 SendablePixelMapNapi* pixelMapNapi = nullptr;
2365 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2366 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
2367 IMAGE_LOGE("SetAlphaSync fail to unwrap context"));
2368 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2369 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2370 "Pixelmap has crossed threads . SetAlphaSync failed"),
2371 IMAGE_LOGE("Pixelmap has crossed threads . SetAlphaSync failed"));
2372
2373 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2374 status = pixelMapNapi->nativePixelMap_->SetAlpha(
2375 static_cast<float>(alpha));
2376 if (status != SUCCESS) {
2377 IMAGE_LOGE("SetAlphaSync failed");
2378 }
2379 } else {
2380 IMAGE_LOGE("Null native ref");
2381 }
2382 return result;
2383 }
2384
ScaleExec(napi_env env,PixelMapAsyncContext * context)2385 static void ScaleExec(napi_env env, PixelMapAsyncContext* context)
2386 {
2387 if (context == nullptr) {
2388 IMAGE_LOGE("Null context");
2389 return;
2390 }
2391 if (context->status == SUCCESS) {
2392 if (context->rPixelMap != nullptr) {
2393 context->rPixelMap->scale(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
2394 context->status = SUCCESS;
2395 } else {
2396 IMAGE_LOGE("Null native ref");
2397 context->status = ERR_IMAGE_INIT_ABNORMAL;
2398 }
2399 } else {
2400 IMAGE_LOGD("Scale has failed. do nothing");
2401 }
2402 }
2403
Scale(napi_env env,napi_callback_info info)2404 napi_value SendablePixelMapNapi::Scale(napi_env env, napi_callback_info info)
2405 {
2406 std::unique_lock<std::shared_mutex> lock(mutex_);
2407 NapiValues nVal;
2408 nVal.argc = NUM_3;
2409 napi_value argValue[NUM_3] = {0};
2410 nVal.argv = argValue;
2411 if (!prepareNapiEnv(env, info, &nVal)) {
2412 return nVal.result;
2413 }
2414 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2415
2416 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
2417 IMAGE_LOGE("Invalid args count %{public}zu", nVal.argc);
2418 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2419 } else {
2420 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
2421 IMAGE_LOGE("Arg 0 type mismatch");
2422 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2423 }
2424 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
2425 IMAGE_LOGE("Arg 1 type mismatch");
2426 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2427 }
2428 }
2429 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2430 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2431 }
2432
2433 if (nVal.context->callbackRef == nullptr) {
2434 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2435 }
2436 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2437 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Scale failed",
2438 ERR_RESOURCE_UNAVAILABLE),
2439 NapiSendEvent(env, nVal.context.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE), nVal.result);
2440 napi_value _resource = nullptr;
2441 napi_create_string_utf8(env, "Scale", NAPI_AUTO_LENGTH, &_resource);
2442 nVal.status = napi_create_async_work(env, nullptr, _resource,
2443 [](napi_env env, void *data) {
2444 auto context = static_cast<PixelMapAsyncContext*>(data);
2445 ScaleExec(env, context);
2446 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2447
2448 if (nVal.status == napi_ok) {
2449 nVal.status = napi_queue_async_work_with_qos(env, nVal.context->work, napi_qos_user_initiated);
2450 if (nVal.status == napi_ok) {
2451 nVal.context.release();
2452 } else {
2453 NAPI_CHECK_AND_DELETE_REF(env, nVal.context->callbackRef);
2454 }
2455 }
2456 return nVal.result;
2457 }
2458
ScaleSync(napi_env env,napi_callback_info info)2459 napi_value SendablePixelMapNapi::ScaleSync(napi_env env, napi_callback_info info)
2460 {
2461 std::unique_lock<std::shared_mutex> lock(mutex_);
2462 napi_value result = nullptr;
2463 napi_get_undefined(env, &result);
2464 napi_status napiStatus;
2465 napi_value thisVar = nullptr;
2466 size_t argCount = NUM_2;
2467 napi_value argValue[NUM_2] = {0};
2468 double xArg = 0;
2469 double yArg = 0;
2470 IMAGE_LOGD("ScaleSync IN");
2471 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2472
2473 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to arg info"));
2474
2475 IMG_NAPI_CHECK_RET_D(argCount == NUM_2,
2476 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2477 "Invalid args count"),
2478 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
2479 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napi_get_value_double(env, argValue[NUM_0], &xArg)),
2480 result, IMAGE_LOGE("Arg 0 type mismatch"));
2481 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napi_get_value_double(env, argValue[NUM_1], &yArg)),
2482 result, IMAGE_LOGE("Arg 1 type mismatch"));
2483 SendablePixelMapNapi* pixelMapNapi = nullptr;
2484 napiStatus = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2485 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result,
2486 IMAGE_LOGE("ScaleSync fail to unwrap context"));
2487 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2488 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2489 "Pixelmap has crossed threads . ScaleSync failed"),
2490 IMAGE_LOGE("Pixelmap has crossed threads . ScaleSync failed"));
2491
2492 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2493 pixelMapNapi->nativePixelMap_->scale(static_cast<float>(xArg), static_cast<float>(yArg));
2494 } else {
2495 IMAGE_LOGE("Null native ref");
2496 }
2497 return result;
2498 }
2499
TranslateExec(napi_env env,PixelMapAsyncContext * context)2500 static void TranslateExec(napi_env env, PixelMapAsyncContext* context)
2501 {
2502 if (context == nullptr) {
2503 IMAGE_LOGE("Null context");
2504 return;
2505 }
2506 if (context->status == SUCCESS) {
2507 if (context->rPixelMap != nullptr) {
2508 context->rPixelMap->translate(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
2509 context->status = SUCCESS;
2510 } else {
2511 IMAGE_LOGE("Null native ref");
2512 context->status = ERR_IMAGE_INIT_ABNORMAL;
2513 }
2514 } else {
2515 IMAGE_LOGD("Translate has failed. do nothing");
2516 }
2517 }
2518
Translate(napi_env env,napi_callback_info info)2519 napi_value SendablePixelMapNapi::Translate(napi_env env, napi_callback_info info)
2520 {
2521 std::unique_lock<std::shared_mutex> lock(mutex_);
2522 NapiValues nVal;
2523 nVal.argc = NUM_3;
2524 napi_value argValue[NUM_3] = {0};
2525 nVal.argv = argValue;
2526 if (!prepareNapiEnv(env, info, &nVal)) {
2527 return nVal.result;
2528 }
2529 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2530
2531 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
2532 IMAGE_LOGE("Invalid args count");
2533 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2534 } else {
2535 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
2536 IMAGE_LOGE("Arg 0 type mismatch");
2537 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2538 }
2539 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
2540 IMAGE_LOGE("Arg 1 type mismatch");
2541 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2542 }
2543 }
2544 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2545 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2546 }
2547
2548 if (nVal.context->callbackRef == nullptr) {
2549 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2550 }
2551 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2552 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Translate failed",
2553 ERR_RESOURCE_UNAVAILABLE),
2554 NapiSendEvent(env, nVal.context.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE), nVal.result);
2555 napi_value _resource = nullptr;
2556 napi_create_string_utf8(env, "Translate", NAPI_AUTO_LENGTH, &_resource);
2557 nVal.status = napi_create_async_work(env, nullptr, _resource,
2558 [](napi_env env, void *data) {
2559 auto context = static_cast<PixelMapAsyncContext*>(data);
2560 TranslateExec(env, context);
2561 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2562
2563 if (nVal.status == napi_ok) {
2564 nVal.status = napi_queue_async_work(env, nVal.context->work);
2565 if (nVal.status == napi_ok) {
2566 nVal.context.release();
2567 } else {
2568 NAPI_CHECK_AND_DELETE_REF(env, nVal.context->callbackRef);
2569 }
2570 }
2571 return nVal.result;
2572 }
2573
TranslateSync(napi_env env,napi_callback_info info)2574 napi_value SendablePixelMapNapi::TranslateSync(napi_env env, napi_callback_info info)
2575 {
2576 std::unique_lock<std::shared_mutex> lock(mutex_);
2577 napi_value result = nullptr;
2578 napi_get_undefined(env, &result);
2579 napi_status napiStatus;
2580 napi_value thisVar = nullptr;
2581 size_t argCount = NUM_2;
2582 napi_value argValue[NUM_2] = {0};
2583 double x = 0;
2584 double y = 0;
2585
2586 IMAGE_LOGD("TranslateSync IN");
2587 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2588 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2589 IMG_NAPI_CHECK_RET_D(argCount == NUM_2,
2590 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2591 "TranslateSync failed"),
2592 IMAGE_LOGE("TranslateSync failed, invalid parameter"));
2593
2594 if (napi_ok != napi_get_value_double(env, argValue[NUM_0], &x) ||
2595 napi_ok != napi_get_value_double(env, argValue[NUM_1], &y)) {
2596 IMAGE_LOGE("get arraybuffer info failed");
2597 return result;
2598 }
2599
2600 SendablePixelMapNapi* pixelMapNapi = nullptr;
2601 napiStatus = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2602 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result,
2603 IMAGE_LOGE("TranslateSync fail to unwrap context"));
2604 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2605 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2606 "Pixelmap has crossed threads . TranslateSync failed"),
2607 IMAGE_LOGE("Pixelmap has crossed threads . TranslateSync failed"));
2608
2609 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2610 pixelMapNapi->nativePixelMap_->translate(static_cast<float>(x), static_cast<float>(y));
2611 } else {
2612 IMAGE_LOGE("Null native ref");
2613 }
2614 return result;
2615 }
2616
RotateExec(napi_env env,PixelMapAsyncContext * context)2617 static void RotateExec(napi_env env, PixelMapAsyncContext* context)
2618 {
2619 if (context == nullptr) {
2620 IMAGE_LOGE("Null context");
2621 return;
2622 }
2623 if (context->status == SUCCESS) {
2624 if (context->rPixelMap != nullptr) {
2625 context->rPixelMap->rotate(context->xArg);
2626 context->status = SUCCESS;
2627 } else {
2628 IMAGE_LOGE("Null native ref");
2629 context->status = ERR_IMAGE_INIT_ABNORMAL;
2630 }
2631 } else {
2632 IMAGE_LOGD("Rotate has failed. do nothing");
2633 }
2634 }
2635
Rotate(napi_env env,napi_callback_info info)2636 napi_value SendablePixelMapNapi::Rotate(napi_env env, napi_callback_info info)
2637 {
2638 std::unique_lock<std::shared_mutex> lock(mutex_);
2639 NapiValues nVal;
2640 nVal.argc = NUM_2;
2641 napi_value argValue[NUM_2] = {0};
2642 nVal.argv = argValue;
2643 IMAGE_LOGD("Rotate IN");
2644 if (!prepareNapiEnv(env, info, &nVal)) {
2645 return nVal.result;
2646 }
2647 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2648
2649 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
2650 IMAGE_LOGE("Invalid args count");
2651 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2652 } else {
2653 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
2654 IMAGE_LOGE("Arg 0 type mismatch");
2655 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2656 }
2657 }
2658 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2659 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2660 }
2661
2662 if (nVal.context->callbackRef == nullptr) {
2663 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2664 }
2665 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2666 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Rotate failed",
2667 ERR_RESOURCE_UNAVAILABLE),
2668 NapiSendEvent(env, nVal.context.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
2669 nVal.result);
2670 napi_value _resource = nullptr;
2671 napi_create_string_utf8(env, "Rotate", NAPI_AUTO_LENGTH, &_resource);
2672 nVal.status = napi_create_async_work(env, nullptr, _resource,
2673 [](napi_env env, void *data) {
2674 auto context = static_cast<PixelMapAsyncContext*>(data);
2675 RotateExec(env, context);
2676 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2677
2678 if (nVal.status == napi_ok) {
2679 nVal.status = napi_queue_async_work(env, nVal.context->work);
2680 if (nVal.status == napi_ok) {
2681 nVal.context.release();
2682 } else {
2683 NAPI_CHECK_AND_DELETE_REF(env, nVal.context->callbackRef);
2684 }
2685 }
2686 return nVal.result;
2687 }
2688
RotateSync(napi_env env,napi_callback_info info)2689 napi_value SendablePixelMapNapi::RotateSync(napi_env env, napi_callback_info info)
2690 {
2691 std::unique_lock<std::shared_mutex> lock(mutex_);
2692 napi_value result = nullptr;
2693 napi_get_undefined(env, &result);
2694 napi_status napiStatus;
2695 napi_value thisVar = nullptr;
2696 size_t argCount = NUM_1;
2697 napi_value argValue[NUM_1] = {0};
2698 double angle = 0;
2699
2700 IMAGE_LOGD("RotateSync IN");
2701 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2702 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2703 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
2704 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2705 "RotateSync failed"),
2706 IMAGE_LOGE("RotateSync failed, invalid parameter"));
2707 napiStatus = napi_get_value_double(env, argValue[NUM_0], &angle);
2708 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
2709
2710 SendablePixelMapNapi* pixelMapNapi = nullptr;
2711 napiStatus = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2712 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result,
2713 IMAGE_LOGE("RotateSync fail to unwrap context"));
2714 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2715 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2716 "Pixelmap has crossed threads . RotateSync failed"),
2717 IMAGE_LOGE("Pixelmap has crossed threads . RotateSync failed"));
2718
2719 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2720 pixelMapNapi->nativePixelMap_->rotate(static_cast<float>(angle));
2721 } else {
2722 IMAGE_LOGE("Null native ref");
2723 }
2724 return result;
2725 }
FlipExec(napi_env env,PixelMapAsyncContext * context)2726 static void FlipExec(napi_env env, PixelMapAsyncContext* context)
2727 {
2728 if (context == nullptr) {
2729 IMAGE_LOGE("Null context");
2730 return;
2731 }
2732 if (context->status == SUCCESS) {
2733 if (context->rPixelMap != nullptr) {
2734 context->rPixelMap->flip(context->xBarg, context->yBarg);
2735 context->status = SUCCESS;
2736 } else {
2737 IMAGE_LOGE("Null native ref");
2738 context->status = ERR_IMAGE_INIT_ABNORMAL;
2739 }
2740 } else {
2741 IMAGE_LOGD("Flip has failed. do nothing");
2742 }
2743 }
2744
Flip(napi_env env,napi_callback_info info)2745 napi_value SendablePixelMapNapi::Flip(napi_env env, napi_callback_info info)
2746 {
2747 std::unique_lock<std::shared_mutex> lock(mutex_);
2748 NapiValues nVal;
2749 nVal.argc = NUM_3;
2750 napi_value argValue[NUM_3] = {0};
2751 nVal.argv = argValue;
2752 if (!prepareNapiEnv(env, info, &nVal)) {
2753 return nVal.result;
2754 }
2755 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2756
2757 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
2758 IMAGE_LOGE("Invalid args count");
2759 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2760 } else {
2761 if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_0], &(nVal.context->xBarg))) {
2762 IMAGE_LOGE("Arg 0 type mismatch");
2763 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2764 }
2765 if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_1], &(nVal.context->yBarg))) {
2766 IMAGE_LOGE("Arg 1 type mismatch");
2767 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2768 }
2769 }
2770 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2771 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2772 }
2773
2774 if (nVal.context->callbackRef == nullptr) {
2775 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2776 }
2777 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2778 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Flip failed",
2779 ERR_RESOURCE_UNAVAILABLE),
2780 NapiSendEvent(env, nVal.context.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE), nVal.result);
2781 napi_value _resource = nullptr;
2782 napi_create_string_utf8(env, "Flip", NAPI_AUTO_LENGTH, &_resource);
2783 nVal.status = napi_create_async_work(env, nullptr, _resource,
2784 [](napi_env env, void *data) {
2785 auto context = static_cast<PixelMapAsyncContext*>(data);
2786 FlipExec(env, context);
2787 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2788
2789 if (nVal.status == napi_ok) {
2790 nVal.status = napi_queue_async_work(env, nVal.context->work);
2791 if (nVal.status == napi_ok) {
2792 nVal.context.release();
2793 } else {
2794 NAPI_CHECK_AND_DELETE_REF(env, nVal.context->callbackRef);
2795 }
2796 }
2797 return nVal.result;
2798 }
2799
FlipSync(napi_env env,napi_callback_info info)2800 napi_value SendablePixelMapNapi::FlipSync(napi_env env, napi_callback_info info)
2801 {
2802 std::unique_lock<std::shared_mutex> lock(mutex_);
2803 napi_value result = nullptr;
2804 napi_get_undefined(env, &result);
2805 napi_status napiStatus;
2806 uint32_t status = SUCCESS;
2807 napi_value thisVar = nullptr;
2808 size_t argCount = NUM_2;
2809 napi_value argValue[NUM_2] = {0};
2810 bool xBarg = 0;
2811 bool yBarg = 0;
2812
2813 IMAGE_LOGD("FlipSync IN");
2814 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2815 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2816 IMG_NAPI_CHECK_RET_D(argCount == NUM_2,
2817 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2818 "FlipSync failed"),
2819 IMAGE_LOGE("FlipSync failed, invalid parameter"));
2820
2821 if (napi_ok != napi_get_value_bool(env, argValue[NUM_0], &xBarg)) {
2822 IMAGE_LOGE("Arg 0 type mismatch");
2823 status = COMMON_ERR_INVALID_PARAMETER;
2824 }
2825 if (napi_ok != napi_get_value_bool(env, argValue[NUM_1], &yBarg)) {
2826 IMAGE_LOGE("Arg 1 type mismatch");
2827 status = COMMON_ERR_INVALID_PARAMETER;
2828 }
2829
2830 IMG_NAPI_CHECK_RET_D(status == SUCCESS, result, IMAGE_LOGE("FlipSync failed, invalid parameter"));
2831
2832 SendablePixelMapNapi* pixelMapNapi = nullptr;
2833 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2834 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
2835 IMAGE_LOGE("FlipSync fail to unwrap context"));
2836 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2837 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2838 "Pixelmap has crossed threads . FlipSync failed"),
2839 IMAGE_LOGE("Pixelmap has crossed threads . FlipSync failed"));
2840
2841 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2842 pixelMapNapi->nativePixelMap_->flip(xBarg, yBarg);
2843 } else {
2844 IMAGE_LOGE("Null native ref");
2845 }
2846 return result;
2847 }
2848
CropExec(napi_env env,PixelMapAsyncContext * context)2849 static void CropExec(napi_env env, PixelMapAsyncContext* context)
2850 {
2851 if (context == nullptr) {
2852 IMAGE_LOGE("Null context");
2853 return;
2854 }
2855 if (context->status == SUCCESS) {
2856 if (context->rPixelMap != nullptr) {
2857 context->status = context->rPixelMap->crop(context->area.region);
2858 } else {
2859 IMAGE_LOGE("Null native ref");
2860 context->status = ERR_IMAGE_INIT_ABNORMAL;
2861 }
2862 } else {
2863 IMAGE_LOGD("Crop has failed. do nothing");
2864 }
2865 }
2866
Crop(napi_env env,napi_callback_info info)2867 napi_value SendablePixelMapNapi::Crop(napi_env env, napi_callback_info info)
2868 {
2869 std::unique_lock<std::shared_mutex> lock(mutex_);
2870 NapiValues nVal;
2871 nVal.argc = NUM_2;
2872 napi_value argValue[NUM_2] = {0};
2873 nVal.argv = argValue;
2874 IMAGE_LOGD("Crop IN");
2875 if (!prepareNapiEnv(env, info, &nVal)) {
2876 return nVal.result;
2877 }
2878 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2879
2880 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
2881 IMAGE_LOGE("Invalid args count");
2882 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2883 } else {
2884 if (!parseRegion(env, nVal.argv[NUM_0], &(nVal.context->area.region))) {
2885 IMAGE_LOGE("Region type mismatch");
2886 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2887 }
2888 }
2889 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2890 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2891 }
2892
2893 if (nVal.context->callbackRef == nullptr) {
2894 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2895 }
2896 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2897 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Crop failed",
2898 ERR_RESOURCE_UNAVAILABLE),
2899 NapiSendEvent(env, nVal.context.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
2900 nVal.result);
2901 napi_value _resource = nullptr;
2902 napi_create_string_utf8(env, "CropExec", NAPI_AUTO_LENGTH, &_resource);
2903 nVal.status = napi_create_async_work(env, nullptr, _resource,
2904 [](napi_env env, void *data) {
2905 auto context = static_cast<PixelMapAsyncContext*>(data);
2906 CropExec(env, context);
2907 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2908
2909 if (nVal.status == napi_ok) {
2910 nVal.status = napi_queue_async_work(env, nVal.context->work);
2911 if (nVal.status == napi_ok) {
2912 nVal.context.release();
2913 } else {
2914 NAPI_CHECK_AND_DELETE_REF(env, nVal.context->callbackRef);
2915 }
2916 }
2917 return nVal.result;
2918 }
2919
CropSync(napi_env env,napi_callback_info info)2920 napi_value SendablePixelMapNapi::CropSync(napi_env env, napi_callback_info info)
2921 {
2922 std::unique_lock<std::shared_mutex> lock(mutex_);
2923 napi_value result = nullptr;
2924 napi_get_undefined(env, &result);
2925 napi_status napiStatus;
2926 uint32_t status = SUCCESS;
2927 napi_value thisVar = nullptr;
2928 size_t argCount = NUM_1;
2929 napi_value argValue[NUM_1] = {0};
2930 Rect region;
2931
2932 IMAGE_LOGD("CropSync IN");
2933 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2934 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2935 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
2936 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2937 "CropSync failed"),
2938 IMAGE_LOGE("CropSync failed, invalid parameter"));
2939 if (!parseRegion(env, argValue[NUM_0], ®ion)) {
2940 IMAGE_LOGE("Region type mismatch");
2941 return result;
2942 }
2943
2944 SendablePixelMapNapi* pixelMapNapi = nullptr;
2945 status = NapiUnwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2946 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result,
2947 IMAGE_LOGE("CropSync fail to unwrap context"));
2948 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2949 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2950 "Pixelmap has crossed threads . CropSync failed"),
2951 IMAGE_LOGE("Pixelmap has crossed threads . CropSync failed"));
2952
2953 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2954 status = pixelMapNapi->nativePixelMap_->crop(region);
2955 if (status != SUCCESS) {
2956 IMAGE_LOGE("CropSync failed");
2957 }
2958 } else {
2959 IMAGE_LOGE("Null native ref");
2960 }
2961 return result;
2962 }
2963
GetColorSpace(napi_env env,napi_callback_info info)2964 napi_value SendablePixelMapNapi::GetColorSpace(napi_env env, napi_callback_info info)
2965 {
2966 std::shared_lock<std::shared_mutex> lock(mutex_);
2967 NapiValues nVal;
2968 nVal.argc = NUM_0;
2969 IMAGE_LOGD("GetColorSpace IN");
2970 napi_get_undefined(env, &nVal.result);
2971 if (!prepareNapiEnv(env, info, &nVal)) {
2972 return ImageNapiUtils::ThrowExceptionError(
2973 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
2974 }
2975 if (nVal.argc != NUM_0) {
2976 return ImageNapiUtils::ThrowExceptionError(
2977 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
2978 }
2979 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
2980 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2981 "Pixelmap has crossed threads . GetColorSpace failed"),
2982 IMAGE_LOGE("Pixelmap has crossed threads . GetColorSpace failed"));
2983 #ifdef IMAGE_COLORSPACE_FLAG
2984 if (nVal.context->nConstructor->nativePixelMap_ == nullptr) {
2985 return ImageNapiUtils::ThrowExceptionError(
2986 env, ERR_IMAGE_DATA_ABNORMAL, "Invalid native pixelmap");
2987 }
2988 auto grCS = nVal.context->nConstructor->nativePixelMap_->InnerGetGrColorSpacePtr();
2989 if (grCS == nullptr) {
2990 return ImageNapiUtils::ThrowExceptionError(
2991 env, ERR_IMAGE_DATA_UNSUPPORT, "No colorspace in pixelmap");
2992 }
2993 auto resultValue = ColorManager::CreateJsColorSpaceObject(env, grCS);
2994 nVal.result = reinterpret_cast<napi_value>(resultValue);
2995 #else
2996 return ImageNapiUtils::ThrowExceptionError(
2997 env, ERR_INVALID_OPERATION, "Unsupported operation");
2998 #endif
2999 return nVal.result;
3000 }
3001
SetColorSpace(napi_env env,napi_callback_info info)3002 napi_value SendablePixelMapNapi::SetColorSpace(napi_env env, napi_callback_info info)
3003 {
3004 std::unique_lock<std::shared_mutex> lock(mutex_);
3005 NapiValues nVal;
3006 nVal.argc = NUM_1;
3007 napi_value argValue[NUM_1] = {0};
3008 nVal.argv = argValue;
3009 IMAGE_LOGD("SetColorSpace IN");
3010 napi_get_undefined(env, &nVal.result);
3011 if (!prepareNapiEnv(env, info, &nVal)) {
3012 return ImageNapiUtils::ThrowExceptionError(
3013 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
3014 }
3015 if (nVal.argc != NUM_1) {
3016 return ImageNapiUtils::ThrowExceptionError(
3017 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
3018 }
3019 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
3020 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3021 "Pixelmap has crossed threads . SetColorSpace failed"),
3022 IMAGE_LOGE("Pixelmap has crossed threads . SetColorSpace failed"));
3023 #ifdef IMAGE_COLORSPACE_FLAG
3024 nVal.context->colorSpace = ColorManager::GetColorSpaceByJSObject(env, nVal.argv[NUM_0]);
3025 if (nVal.context->colorSpace == nullptr) {
3026 return ImageNapiUtils::ThrowExceptionError(
3027 env, ERR_IMAGE_INVALID_PARAMETER, "ColorSpace mismatch");
3028 }
3029 nVal.context->nConstructor->nativePixelMap_->InnerSetColorSpace(*(nVal.context->colorSpace));
3030 #else
3031 return ImageNapiUtils::ThrowExceptionError(
3032 env, ERR_INVALID_OPERATION, "Unsupported operation");
3033 #endif
3034 return nVal.result;
3035 }
3036
Marshalling(napi_env env,napi_callback_info info)3037 napi_value SendablePixelMapNapi::Marshalling(napi_env env, napi_callback_info info)
3038 {
3039 std::unique_lock<std::shared_mutex> lock(mutex_);
3040 NapiValues nVal;
3041 nVal.argc = NUM_1;
3042 napi_value argValue[NUM_1] = {0};
3043 nVal.argv = argValue;
3044 IMAGE_LOGD("Marshalling IN");
3045
3046 if (!prepareNapiEnv(env, info, &nVal)) {
3047 return ImageNapiUtils::ThrowExceptionError(
3048 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
3049 }
3050 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3051 if (nVal.argc != NUM_0 && nVal.argc != NUM_1) {
3052 return ImageNapiUtils::ThrowExceptionError(
3053 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
3054 }
3055 NAPI_MessageSequence *napiSequence = nullptr;
3056 napi_get_cb_info(env, info, &nVal.argc, nVal.argv, nullptr, nullptr);
3057 NapiUnwrap(env, nVal.argv[0], reinterpret_cast<void**>(&napiSequence));
3058 IMG_NAPI_CHECK_RET_D(IMG_NOT_NULL(napiSequence), nullptr,
3059 IMAGE_LOGE("Marshalling fail to unwrap context"));
3060 auto messageParcel = napiSequence->GetMessageParcel();
3061 bool st = nVal.context->rPixelMap->Marshalling(*messageParcel);
3062 if (!st) {
3063 return ImageNapiUtils::ThrowExceptionError(
3064 env, ERR_IPC, "marshalling pixel map to parcel failed.");
3065 }
3066 return nVal.result;
3067 }
3068
ApplyColorSpaceExec(napi_env env,PixelMapAsyncContext * context)3069 static void ApplyColorSpaceExec(napi_env env, PixelMapAsyncContext* context)
3070 {
3071 if (context == nullptr) {
3072 IMAGE_LOGE("Null context");
3073 return;
3074 }
3075 if (context->status != SUCCESS) {
3076 IMAGE_LOGD("ApplyColorSpace has failed. do nothing");
3077 return;
3078 }
3079 if (context->rPixelMap == nullptr || context->colorSpace == nullptr) {
3080 context->status = ERR_IMAGE_INIT_ABNORMAL;
3081 IMAGE_LOGE("ApplyColorSpace Null native ref");
3082 return;
3083 }
3084 context->status = context->rPixelMap->ApplyColorSpace(*(context->colorSpace));
3085 }
3086
ParseColorSpaceVal(napi_env env,napi_value val,PixelMapAsyncContext * context)3087 static void ParseColorSpaceVal(napi_env env, napi_value val, PixelMapAsyncContext* context)
3088 {
3089 if (context == nullptr) {
3090 IMAGE_LOGE("Null context");
3091 return;
3092 }
3093
3094 #ifdef IMAGE_COLORSPACE_FLAG
3095 context->colorSpace = ColorManager::GetColorSpaceByJSObject(env, val);
3096 if (context->colorSpace == nullptr) {
3097 context->status = ERR_IMAGE_INVALID_PARAMETER;
3098 }
3099 #else
3100 Val.context->status = ERR_IMAGE_DATA_UNSUPPORT;
3101 #endif
3102 }
3103
ApplyColorSpace(napi_env env,napi_callback_info info)3104 napi_value SendablePixelMapNapi::ApplyColorSpace(napi_env env, napi_callback_info info)
3105 {
3106 std::unique_lock<std::shared_mutex> lock(mutex_);
3107 NapiValues nVal;
3108 nVal.argc = NUM_2;
3109 napi_value argValue[NUM_2] = {0};
3110 nVal.argv = argValue;
3111 IMAGE_LOGD("ApplyColorSpace IN");
3112 if (!prepareNapiEnv(env, info, &nVal)) {
3113 return nVal.result;
3114 }
3115 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3116
3117 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
3118 IMAGE_LOGE("Invalid args count");
3119 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3120 } else {
3121 ParseColorSpaceVal(env, nVal.argv[NUM_0], nVal.context.get());
3122 }
3123 if (nVal.argc >= NUM_1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
3124 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
3125 }
3126
3127 if (nVal.context->callbackRef == nullptr) {
3128 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
3129 }
3130 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
3131 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . ApplyColorSpace failed",
3132 ERR_RESOURCE_UNAVAILABLE),
3133 NapiSendEvent(env, nVal.context.release(), napi_eprio_high, ERR_RESOURCE_UNAVAILABLE),
3134 nVal.result);
3135 napi_value _resource = nullptr;
3136 napi_create_string_utf8(env, "ApplyColorSpace", NAPI_AUTO_LENGTH, &_resource);
3137 nVal.status = napi_create_async_work(env, nullptr, _resource, [](napi_env env, void *data) {
3138 auto context = static_cast<PixelMapAsyncContext*>(data);
3139 ApplyColorSpaceExec(env, context);
3140 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
3141
3142 if (nVal.status == napi_ok) {
3143 nVal.status = napi_queue_async_work(env, nVal.context->work);
3144 if (nVal.status == napi_ok) {
3145 nVal.context.release();
3146 } else {
3147 NAPI_CHECK_AND_DELETE_REF(env, nVal.context->callbackRef);
3148 }
3149 }
3150 return nVal.result;
3151 }
3152
release()3153 void SendablePixelMapNapi::release()
3154 {
3155 if (!isRelease) {
3156 if (nativePixelMap_ != nullptr) {
3157 nativePixelMap_.reset();
3158 }
3159 isRelease = true;
3160 }
3161 }
3162 } // namespace Media
3163 } // namespace OHOS
3164