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