• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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], &region)) {
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