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