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 "pixel_map_napi.h"
17 #include "media_errors.h"
18 #include "image_log.h"
19 #include "image_napi_utils.h"
20 #include "image_pixel_map_napi.h"
21 #include "image_trace.h"
22 #include "log_tags.h"
23 #include "color_space_object_convertor.h"
24 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
25 #include "js_runtime_utils.h"
26 #include "napi_message_sequence.h"
27 #include "pixel_map_from_surface.h"
28 #endif
29 #include "hitrace_meter.h"
30 #include "pixel_map.h"
31
32 #undef LOG_DOMAIN
33 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
34
35 #undef LOG_TAG
36 #define LOG_TAG "PixelMapNapi"
37
38 namespace {
39 constexpr uint32_t NUM_0 = 0;
40 constexpr uint32_t NUM_1 = 1;
41 constexpr uint32_t NUM_2 = 2;
42 constexpr uint32_t NUM_3 = 3;
43 constexpr uint32_t NUM_4 = 4;
44 }
45
46 namespace OHOS {
47 namespace Media {
48 static const std::string CREATE_PIXEL_MAP_FROM_PARCEL = "createPixelMapFromParcel";
49 static const std::string MARSHALLING = "marshalling";
50 static const std::map<std::string, std::set<uint32_t>> ETS_API_ERROR_CODE = {
51 {CREATE_PIXEL_MAP_FROM_PARCEL, {62980096, 62980105, 62980115, 62980097,
52 62980177, 62980178, 62980179, 62980180, 62980246}},
53 {MARSHALLING, {62980115, 62980097, 62980096}}
54 };
55 static const std::string CLASS_NAME = "PixelMap";
56 static const std::int32_t NEW_INSTANCE_ARGC = 1;
57 thread_local napi_ref PixelMapNapi::sConstructor_ = nullptr;
58 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
59 NAPI_MessageSequence* napi_messageSequence = nullptr;
60 #endif
61
62 static std::mutex pixelMapCrossThreadMutex_;
63 struct PositionArea {
64 void* pixels;
65 size_t size;
66 uint32_t offset;
67 uint32_t stride;
68 Rect region;
69 };
70
71 struct PixelMapAsyncContext {
72 napi_env env;
73 napi_async_work work;
74 napi_deferred deferred;
75 napi_ref callbackRef;
76 napi_ref error = nullptr;
77 uint32_t status;
78 PixelMapNapi *nConstructor;
79 void* colorsBuffer;
80 size_t colorsBufferSize;
81 InitializationOptions opts;
82 PositionArea area;
83 std::shared_ptr<PixelMap> rPixelMap;
84 std::shared_ptr<PixelMap> alphaMap;
85 double alpha = -1;
86 uint32_t resultUint32;
87 ImageInfo imageInfo;
88 double xArg = 0;
89 double yArg = 0;
90 bool xBarg = false;
91 bool yBarg = false;
92 std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace;
93 std::string surfaceId;
94 };
95
96 class AgainstTransferGC {
97 public:
98 std::shared_ptr<PixelMap> pixelMap = nullptr;
~AgainstTransferGC()99 ~AgainstTransferGC()
100 {
101 pixelMap = nullptr;
102 }
103 };
104
ParsePixlForamt(int32_t val)105 static PixelFormat ParsePixlForamt(int32_t val)
106 {
107 if (val <= static_cast<int32_t>(PixelFormat::CMYK)) {
108 return PixelFormat(val);
109 }
110
111 return PixelFormat::UNKNOWN;
112 }
113
ParseAlphaType(int32_t val)114 static AlphaType ParseAlphaType(int32_t val)
115 {
116 if (val <= static_cast<int32_t>(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
117 return AlphaType(val);
118 }
119
120 return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
121 }
122
ParseScaleMode(int32_t val)123 static ScaleMode ParseScaleMode(int32_t val)
124 {
125 if (val <= static_cast<int32_t>(ScaleMode::CENTER_CROP)) {
126 return ScaleMode(val);
127 }
128
129 return ScaleMode::FIT_TARGET_SIZE;
130 }
131
parseSize(napi_env env,napi_value root,Size * size)132 static bool parseSize(napi_env env, napi_value root, Size* size)
133 {
134 if (size == nullptr) {
135 return false;
136 }
137
138 if (!GET_INT32_BY_NAME(root, "height", size->height)) {
139 return false;
140 }
141
142 if (!GET_INT32_BY_NAME(root, "width", size->width)) {
143 return false;
144 }
145
146 return true;
147 }
148
parseInitializationOptions(napi_env env,napi_value root,InitializationOptions * opts)149 static bool parseInitializationOptions(napi_env env, napi_value root, InitializationOptions* opts)
150 {
151 uint32_t tmpNumber = 0;
152 napi_value tmpValue = nullptr;
153
154 if (opts == nullptr) {
155 return false;
156 }
157
158 if (!GET_BOOL_BY_NAME(root, "editable", opts->editable)) {
159 opts->editable = true;
160 }
161
162 if (!GET_UINT32_BY_NAME(root, "alphaType", tmpNumber)) {
163 IMAGE_LOGI("no alphaType in initialization options");
164 }
165 opts->alphaType = ParseAlphaType(tmpNumber);
166
167 tmpNumber = 0;
168 if (!GET_UINT32_BY_NAME(root, "pixelFormat", tmpNumber)) {
169 IMAGE_LOGI("no pixelFormat in initialization options");
170 }
171 opts->pixelFormat = ParsePixlForamt(tmpNumber);
172
173 tmpNumber = 0;
174 if (!GET_UINT32_BY_NAME(root, "scaleMode", tmpNumber)) {
175 IMAGE_LOGI("no scaleMode in initialization options");
176 }
177 opts->scaleMode = ParseScaleMode(tmpNumber);
178
179 if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
180 return false;
181 }
182
183 if (!parseSize(env, tmpValue, &(opts->size))) {
184 return false;
185 }
186 return true;
187 }
188
parseRegion(napi_env env,napi_value root,Rect * region)189 static bool parseRegion(napi_env env, napi_value root, Rect* region)
190 {
191 napi_value tmpValue = nullptr;
192
193 if (region == nullptr) {
194 return false;
195 }
196
197 if (!GET_INT32_BY_NAME(root, "x", region->left)) {
198 return false;
199 }
200
201 if (!GET_INT32_BY_NAME(root, "y", region->top)) {
202 return false;
203 }
204
205 if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
206 return false;
207 }
208
209 if (!GET_INT32_BY_NAME(tmpValue, "height", region->height)) {
210 return false;
211 }
212
213 if (!GET_INT32_BY_NAME(tmpValue, "width", region->width)) {
214 return false;
215 }
216
217 return true;
218 }
219
parsePositionArea(napi_env env,napi_value root,PositionArea * area)220 static bool parsePositionArea(napi_env env, napi_value root, PositionArea* area)
221 {
222 napi_value tmpValue = nullptr;
223
224 if (area == nullptr) {
225 return false;
226 }
227
228 if (!GET_BUFFER_BY_NAME(root, "pixels", area->pixels, area->size)) {
229 return false;
230 }
231
232 if (!GET_UINT32_BY_NAME(root, "offset", area->offset)) {
233 return false;
234 }
235
236 if (!GET_UINT32_BY_NAME(root, "stride", area->stride)) {
237 return false;
238 }
239
240 if (!GET_NODE_BY_NAME(root, "region", tmpValue)) {
241 return false;
242 }
243
244 if (!parseRegion(env, tmpValue, &(area->region))) {
245 return false;
246 }
247 return true;
248 }
249
CommonCallbackRoutine(napi_env env,PixelMapAsyncContext * & asyncContext,const napi_value & valueParam)250 static void CommonCallbackRoutine(napi_env env, PixelMapAsyncContext* &asyncContext, const napi_value &valueParam)
251 {
252 napi_value result[NUM_2] = {0};
253 napi_value retVal;
254 napi_value callback = nullptr;
255
256 napi_get_undefined(env, &result[NUM_0]);
257 napi_get_undefined(env, &result[NUM_1]);
258
259 napi_handle_scope scope = nullptr;
260 napi_open_handle_scope(env, &scope);
261 if (scope == nullptr) {
262 return;
263 }
264
265 if (asyncContext == nullptr) {
266 return;
267 }
268 if (asyncContext->status == SUCCESS) {
269 result[NUM_1] = valueParam;
270 } else if (asyncContext->error != nullptr) {
271 napi_get_reference_value(env, asyncContext->error, &result[NUM_0]);
272 napi_delete_reference(env, asyncContext->error);
273 } else {
274 napi_create_uint32(env, asyncContext->status, &result[NUM_0]);
275 }
276
277 if (asyncContext->deferred) {
278 if (asyncContext->status == SUCCESS) {
279 napi_resolve_deferred(env, asyncContext->deferred, result[NUM_1]);
280 } else {
281 napi_reject_deferred(env, asyncContext->deferred, result[NUM_0]);
282 }
283 } else {
284 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
285 napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
286 napi_delete_reference(env, asyncContext->callbackRef);
287 }
288
289 napi_delete_async_work(env, asyncContext->work);
290 napi_close_handle_scope(env, scope);
291
292 delete asyncContext;
293 asyncContext = nullptr;
294 }
295
STATIC_COMPLETE_FUNC(EmptyResult)296 STATIC_COMPLETE_FUNC(EmptyResult)
297 {
298 napi_value result = nullptr;
299 napi_get_undefined(env, &result);
300
301 auto context = static_cast<PixelMapAsyncContext*>(data);
302
303 CommonCallbackRoutine(env, context, result);
304 }
305
STATIC_COMPLETE_FUNC(GeneralError)306 STATIC_COMPLETE_FUNC(GeneralError)
307 {
308 napi_value result = nullptr;
309 napi_get_undefined(env, &result);
310 auto context = static_cast<PixelMapAsyncContext*>(data);
311 context->status = ERR_RESOURCE_UNAVAILABLE;
312 CommonCallbackRoutine(env, context, result);
313 }
314
PixelMapNapi()315 PixelMapNapi::PixelMapNapi():env_(nullptr)
316 {
317 static std::atomic<uint32_t> currentId = 0;
318 uniqueId_ = currentId.fetch_add(1, std::memory_order_relaxed);
319 }
320
~PixelMapNapi()321 PixelMapNapi::~PixelMapNapi()
322 {
323 release();
324 }
325
DoInitAfter(napi_env env,napi_value exports,napi_value constructor,size_t property_count,const napi_property_descriptor * properties)326 static napi_value DoInitAfter(napi_env env,
327 napi_value exports,
328 napi_value constructor,
329 size_t property_count,
330 const napi_property_descriptor* properties)
331 {
332 napi_value global = nullptr;
333 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
334 napi_get_global(env, &global)),
335 nullptr, IMAGE_LOGE("Init:get global fail")
336 );
337
338 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
339 napi_set_named_property(env, global, CLASS_NAME.c_str(), constructor)),
340 nullptr, IMAGE_LOGE("Init:set global named property fail")
341 );
342
343 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
344 napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor)),
345 nullptr, IMAGE_LOGE("set named property fail")
346 );
347
348 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
349 napi_define_properties(env, exports, property_count, properties)),
350 nullptr, IMAGE_LOGE("define properties fail")
351 );
352 return exports;
353 }
354
Init(napi_env env,napi_value exports)355 napi_value PixelMapNapi::Init(napi_env env, napi_value exports)
356 {
357 napi_property_descriptor props[] = {
358 DECLARE_NAPI_FUNCTION("readPixelsToBuffer", ReadPixelsToBuffer),
359 DECLARE_NAPI_FUNCTION("readPixels", ReadPixels),
360 DECLARE_NAPI_FUNCTION("writePixels", WritePixels),
361 DECLARE_NAPI_FUNCTION("writeBufferToPixels", WriteBufferToPixels),
362 DECLARE_NAPI_FUNCTION("getImageInfo", GetImageInfo),
363 DECLARE_NAPI_FUNCTION("getBytesNumberPerRow", GetBytesNumberPerRow),
364 DECLARE_NAPI_FUNCTION("getPixelBytesNumber", GetPixelBytesNumber),
365 DECLARE_NAPI_FUNCTION("isSupportAlpha", IsSupportAlpha),
366 DECLARE_NAPI_FUNCTION("setAlphaAble", SetAlphaAble),
367 DECLARE_NAPI_FUNCTION("createAlphaPixelmap", CreateAlphaPixelmap),
368 DECLARE_NAPI_FUNCTION("getDensity", GetDensity),
369 DECLARE_NAPI_FUNCTION("setDensity", SetDensity),
370 DECLARE_NAPI_FUNCTION("opacity", SetAlpha),
371 DECLARE_NAPI_FUNCTION("release", Release),
372 DECLARE_NAPI_FUNCTION("scale", Scale),
373 DECLARE_NAPI_FUNCTION("translate", Translate),
374 DECLARE_NAPI_FUNCTION("rotate", Rotate),
375 DECLARE_NAPI_FUNCTION("flip", Flip),
376 DECLARE_NAPI_FUNCTION("crop", Crop),
377 DECLARE_NAPI_FUNCTION("getColorSpace", GetColorSpace),
378 DECLARE_NAPI_FUNCTION("setColorSpace", SetColorSpace),
379 DECLARE_NAPI_FUNCTION("applyColorSpace", ApplyColorSpace),
380 DECLARE_NAPI_FUNCTION("marshalling", Marshalling),
381 DECLARE_NAPI_FUNCTION("unmarshalling", Unmarshalling),
382 DECLARE_NAPI_GETTER("isEditable", GetIsEditable),
383 DECLARE_NAPI_GETTER("isStrideAlignment", GetIsStrideAlignment),
384 };
385
386 napi_property_descriptor static_prop[] = {
387 DECLARE_NAPI_STATIC_FUNCTION("createPixelMap", CreatePixelMap),
388 DECLARE_NAPI_STATIC_FUNCTION("unmarshalling", Unmarshalling),
389 DECLARE_NAPI_STATIC_FUNCTION(CREATE_PIXEL_MAP_FROM_PARCEL.c_str(), CreatePixelMapFromParcel),
390 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
391 DECLARE_NAPI_STATIC_FUNCTION("createPixelMapFromSurface", CreatePixelMapFromSurface),
392 #endif
393 };
394
395 napi_value constructor = nullptr;
396
397 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
398 napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
399 Constructor, nullptr, IMG_ARRAY_SIZE(props),
400 props, &constructor)),
401 nullptr, IMAGE_LOGE("define class fail")
402 );
403
404 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
405 napi_create_reference(env, constructor, 1, &sConstructor_)),
406 nullptr, IMAGE_LOGE("create reference fail")
407 );
408
409 auto result = DoInitAfter(env, exports, constructor,
410 IMG_ARRAY_SIZE(static_prop), static_prop);
411
412 IMAGE_LOGD("Init success");
413 return result;
414 }
415
GetPixelMap(napi_env env,napi_value pixelmap)416 std::shared_ptr<PixelMap> PixelMapNapi::GetPixelMap(napi_env env, napi_value pixelmap)
417 {
418 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
419
420 napi_status status = napi_unwrap(env, pixelmap, reinterpret_cast<void**>(&pixelMapNapi));
421 if (!IMG_IS_OK(status)) {
422 IMAGE_LOGE("GetPixelMap napi unwrap failed");
423 return nullptr;
424 }
425
426 if (pixelMapNapi == nullptr) {
427 IMAGE_LOGE("GetPixelMap pixmapNapi is nullptr");
428 return nullptr;
429 }
430
431 auto pixelmapNapiPtr = pixelMapNapi.release();
432 if (pixelmapNapiPtr == nullptr) {
433 IMAGE_LOGE("GetPixelMap pixelmapNapi is nullptr");
434 return nullptr;
435 }
436 return pixelmapNapiPtr->nativePixelMap_;
437 }
438
GetPixelMap()439 std::shared_ptr<PixelMap>* PixelMapNapi::GetPixelMap()
440 {
441 return &nativePixelMap_;
442 }
443
IsLockPixelMap()444 bool PixelMapNapi::IsLockPixelMap()
445 {
446 return (lockCount > 0);
447 }
448
LockPixelMap()449 bool PixelMapNapi::LockPixelMap()
450 {
451 lockCount++;
452 return true;
453 }
454
UnlockPixelMap()455 void PixelMapNapi::UnlockPixelMap()
456 {
457 if (lockCount > 0) {
458 lockCount--;
459 }
460 }
461
OHOS_MEDIA_GetPixelMap(napi_env env,napi_value value)462 extern "C" __attribute__((visibility("default"))) void* OHOS_MEDIA_GetPixelMap(napi_env env, napi_value value)
463 {
464 PixelMapNapi *pixmapNapi = nullptr;
465 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
466 if (pixmapNapi == nullptr) {
467 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
468 return nullptr;
469 }
470 return reinterpret_cast<void*>(pixmapNapi->GetPixelMap());
471 }
472
OHOS_MEDIA_GetImageInfo(napi_env env,napi_value value,OhosPixelMapInfo * info)473 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_GetImageInfo(napi_env env, napi_value value,
474 OhosPixelMapInfo *info)
475 {
476 IMAGE_LOGD("GetImageInfo IN");
477
478 if (info == nullptr) {
479 IMAGE_LOGE("info is nullptr");
480 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
481 }
482
483 PixelMapNapi *pixmapNapi = nullptr;
484 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
485 if (pixmapNapi == nullptr) {
486 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
487 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
488 }
489
490 std::shared_ptr<PixelMap> pixelMap = pixmapNapi->GetPixelNapiInner();
491 if ((pixelMap == nullptr)) {
492 IMAGE_LOGE("pixelMap is nullptr");
493 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
494 }
495
496 ImageInfo imageInfo;
497 pixelMap->GetImageInfo(imageInfo);
498 info->width = imageInfo.size.width;
499 info->height = imageInfo.size.height;
500 info->rowSize = pixelMap->GetRowStride();
501 info->pixelFormat = static_cast<int32_t>(imageInfo.pixelFormat);
502
503 IMAGE_LOGD("GetImageInfo, w=%{public}u, h=%{public}u, r=%{public}u, f=%{public}d",
504 info->width, info->height, info->rowSize, info->pixelFormat);
505
506 return OHOS_IMAGE_RESULT_SUCCESS;
507 }
508
OHOS_MEDIA_AccessPixels(napi_env env,napi_value value,uint8_t ** addrPtr)509 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_AccessPixels(napi_env env, napi_value value,
510 uint8_t** addrPtr)
511 {
512 IMAGE_LOGI("AccessPixels IN");
513
514 PixelMapNapi *pixmapNapi = nullptr;
515 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
516 if (pixmapNapi == nullptr) {
517 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
518 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
519 }
520
521 std::shared_ptr<PixelMap> pixelMap = pixmapNapi->GetPixelNapiInner();
522 if (pixelMap == nullptr) {
523 IMAGE_LOGE("pixelMap is nullptr");
524 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
525 }
526
527 const uint8_t *constPixels = pixelMap->GetPixels();
528 if (constPixels == nullptr) {
529 IMAGE_LOGE("const pixels is nullptr");
530 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
531 }
532
533 uint8_t *pixels = const_cast<uint8_t*>(constPixels);
534 if (pixels == nullptr) {
535 IMAGE_LOGE("pixels is nullptr");
536 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
537 }
538
539 pixmapNapi->LockPixelMap();
540
541 if (addrPtr != nullptr) {
542 *addrPtr = pixels;
543 }
544
545 IMAGE_LOGD("AccessPixels OUT");
546 return OHOS_IMAGE_RESULT_SUCCESS;
547 }
548
OHOS_MEDIA_UnAccessPixels(napi_env env,napi_value value)549 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_UnAccessPixels(napi_env env, napi_value value)
550 {
551 IMAGE_LOGD("UnAccessPixels IN");
552
553 PixelMapNapi *pixmapNapi = nullptr;
554 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
555 if (pixmapNapi == nullptr) {
556 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
557 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
558 }
559
560 pixmapNapi->UnlockPixelMap();
561
562 return OHOS_IMAGE_RESULT_SUCCESS;
563 }
564
DetachPixelMapFunc(napi_env env,void * value,void *)565 inline void *DetachPixelMapFunc(napi_env env, void *value, void *)
566 {
567 IMAGE_LOGD("DetachPixelMapFunc in");
568 if (value == nullptr) {
569 IMAGE_LOGE("DetachPixelMapFunc value is nullptr");
570 return value;
571 }
572 auto pixelNapi = reinterpret_cast<PixelMapNapi*>(value);
573 pixelNapi->setPixelNapiEditable(false);
574 AgainstTransferGC *data = new AgainstTransferGC();
575 data->pixelMap = pixelNapi->GetPixelNapiInner();
576 return reinterpret_cast<void*>(data);
577 }
578
NewPixelNapiInstance(napi_env & env,napi_value & constructor,std::shared_ptr<PixelMap> & pixelMap,napi_value & result)579 static napi_status NewPixelNapiInstance(napi_env &env, napi_value &constructor,
580 std::shared_ptr<PixelMap> &pixelMap, napi_value &result)
581 {
582 napi_status status;
583 if (pixelMap == nullptr) {
584 status = napi_invalid_arg;
585 IMAGE_LOGE("NewPixelNapiInstance pixelMap is nullptr");
586 return status;
587 }
588 size_t argc = NEW_INSTANCE_ARGC;
589 napi_value argv[NEW_INSTANCE_ARGC] = { 0 };
590 napi_create_int32(env, pixelMap->GetUniqueId(), &argv[0]);
591 PixelMapContainer::GetInstance().Insert(pixelMap->GetUniqueId(), pixelMap);
592 status = napi_new_instance(env, constructor, argc, argv, &result);
593 return status;
594 }
595
AttachPixelMapFunc(napi_env env,void * value,void *)596 napi_value AttachPixelMapFunc(napi_env env, void *value, void *)
597 {
598 if (value == nullptr) {
599 IMAGE_LOGE("attach value is nullptr");
600 return nullptr;
601 }
602 std::lock_guard<std::mutex> lock(pixelMapCrossThreadMutex_);
603
604 napi_value result = nullptr;
605 if (value == nullptr) {
606 IMAGE_LOGE("attach value lock losed");
607 napi_get_undefined(env, &result);
608 return result;
609 }
610 AgainstTransferGC *data = reinterpret_cast<AgainstTransferGC*>(value);
611 std::shared_ptr<PixelMap> attachPixelMap = std::move(data->pixelMap);
612 delete data;
613 if (attachPixelMap == nullptr) {
614 IMAGE_LOGE("AttachPixelMapFunc attachPixelMap is nullptr");
615 napi_get_undefined(env, &result);
616 return result;
617 }
618 napi_value constructor = nullptr;
619 napi_status status;
620
621 if (PixelMapNapi::GetConstructor() == nullptr) {
622 IMAGE_LOGI("PixelMapNapi::GetConstructor() is nullptr");
623 napi_value exports = nullptr;
624 napi_create_object(env, &exports);
625 PixelMapNapi::Init(env, exports);
626 }
627 napi_value globalValue;
628 napi_get_global(env, &globalValue);
629 status = napi_get_named_property(env, globalValue, CLASS_NAME.c_str(), &constructor);
630 if (!IMG_IS_OK(status)) {
631 IMAGE_LOGI("napi_get_named_property failed requireNapi in");
632 napi_value func;
633 napi_get_named_property(env, globalValue, "requireNapi", &func);
634
635 napi_value imageInfo;
636 napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
637 napi_value funcArgv[1] = { imageInfo };
638 napi_value returnValue;
639 napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
640 status = napi_get_named_property(env, globalValue, CLASS_NAME.c_str(), &constructor);
641 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("napi_get_named_property error"));
642 }
643
644 status = NewPixelNapiInstance(env, constructor, attachPixelMap, result);
645 if (!IMG_IS_OK(status)) {
646 IMAGE_LOGE("AttachPixelMapFunc napi_get_referencce_value failed");
647 }
648 return result;
649 }
650
Constructor(napi_env env,napi_callback_info info)651 napi_value PixelMapNapi::Constructor(napi_env env, napi_callback_info info)
652 {
653 napi_value undefineVar = nullptr;
654 napi_get_undefined(env, &undefineVar);
655
656 napi_status status;
657 napi_value thisVar = nullptr;
658 napi_get_undefined(env, &thisVar);
659 size_t argc = NEW_INSTANCE_ARGC;
660 napi_value argv[NEW_INSTANCE_ARGC] = { 0 };
661 IMAGE_LOGD("Constructor IN");
662 status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
663 IMG_NAPI_CHECK_RET(IMG_IS_READY(status, thisVar), undefineVar);
664 uint32_t pixelMapId = 0;
665 napi_get_value_uint32(env, argv[0], &pixelMapId);
666 std::unique_ptr<PixelMapNapi> pPixelMapNapi = std::make_unique<PixelMapNapi>();
667
668 IMG_NAPI_CHECK_RET(IMG_NOT_NULL(pPixelMapNapi), undefineVar);
669
670 pPixelMapNapi->env_ = env;
671 if (PixelMapContainer::GetInstance().Find(pixelMapId)) {
672 pPixelMapNapi->nativePixelMap_ = PixelMapContainer::GetInstance()[pixelMapId];
673 IMAGE_LOGD("Constructor in napi_id:%{public}d, id:%{public}d",
674 pPixelMapNapi->GetUniqueId(), pPixelMapNapi->nativePixelMap_->GetUniqueId());
675 } else {
676 IMAGE_LOGE("Constructor nativePixelMap is nullptr");
677 }
678
679 napi_coerce_to_native_binding_object(
680 env, thisVar, DetachPixelMapFunc, AttachPixelMapFunc, pPixelMapNapi.get(), nullptr);
681
682 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(pPixelMapNapi.get()),
683 PixelMapNapi::Destructor, nullptr, nullptr);
684 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), undefineVar, IMAGE_LOGE("Failure wrapping js to native napi"));
685
686 pPixelMapNapi.release();
687 PixelMapContainer::GetInstance().Erase(pixelMapId);
688 return thisVar;
689 }
690
Destructor(napi_env env,void * nativeObject,void * finalize)691 void PixelMapNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
692 {
693 if (nativeObject != nullptr) {
694 std::lock_guard<std::mutex> lock(pixelMapCrossThreadMutex_);
695 IMAGE_LOGD("Destructor pixelmapNapi");
696 delete reinterpret_cast<PixelMapNapi*>(nativeObject);
697 nativeObject = nullptr;
698 }
699 }
700
BuildContextError(napi_env env,napi_ref & error,const std::string errMsg,const int32_t errCode)701 static void BuildContextError(napi_env env, napi_ref &error, const std::string errMsg, const int32_t errCode)
702 {
703 IMAGE_LOGE("%{public}s", errMsg.c_str());
704 napi_value tmpError;
705 ImageNapiUtils::CreateErrorObj(env, tmpError, errCode, errMsg);
706 napi_create_reference(env, tmpError, NUM_1, &(error));
707 }
708
STATIC_EXEC_FUNC(CreatePixelMap)709 STATIC_EXEC_FUNC(CreatePixelMap)
710 {
711 auto context = static_cast<PixelMapAsyncContext*>(data);
712 auto colors = static_cast<uint32_t*>(context->colorsBuffer);
713 auto pixelmap = PixelMap::Create(colors, context->colorsBufferSize, context->opts);
714
715 context->rPixelMap = std::move(pixelmap);
716
717 if (IMG_NOT_NULL(context->rPixelMap)) {
718 context->status = SUCCESS;
719 } else {
720 context->status = ERROR;
721 }
722 }
723
CreatePixelMapComplete(napi_env env,napi_status status,void * data)724 void PixelMapNapi::CreatePixelMapComplete(napi_env env, napi_status status, void *data)
725 {
726 napi_value constructor = nullptr;
727 napi_value result = nullptr;
728
729 IMAGE_LOGD("CreatePixelMapComplete IN");
730 auto context = static_cast<PixelMapAsyncContext*>(data);
731
732 status = napi_get_reference_value(env, sConstructor_, &constructor);
733
734 if (IMG_IS_OK(status)) {
735 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
736 }
737
738 if (!IMG_IS_OK(status)) {
739 context->status = ERROR;
740 IMAGE_LOGE("New instance could not be obtained");
741 napi_get_undefined(env, &result);
742 }
743
744 CommonCallbackRoutine(env, context, result);
745 }
746
CreatePixelMap(napi_env env,napi_callback_info info)747 napi_value PixelMapNapi::CreatePixelMap(napi_env env, napi_callback_info info)
748 {
749 if (PixelMapNapi::GetConstructor() == nullptr) {
750 napi_value exports = nullptr;
751 napi_create_object(env, &exports);
752 PixelMapNapi::Init(env, exports);
753 }
754
755 napi_value result = nullptr;
756 napi_get_undefined(env, &result);
757
758 int32_t refCount = 1;
759
760 napi_status status;
761 napi_value thisVar = nullptr;
762 napi_value argValue[NUM_4] = {0};
763 size_t argCount = NUM_4;
764 IMAGE_LOGD("CreatePixelMap IN");
765
766 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
767
768 // we are static method!
769 // thisVar is nullptr here
770 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
771 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
772
773 status = napi_get_arraybuffer_info(env, argValue[NUM_0], &(asyncContext->colorsBuffer),
774 &(asyncContext->colorsBufferSize));
775
776 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
777
778 IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[1], &(asyncContext->opts)),
779 nullptr, IMAGE_LOGE("InitializationOptions mismatch"));
780
781 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
782 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
783 }
784
785 if (asyncContext->callbackRef == nullptr) {
786 napi_create_promise(env, &(asyncContext->deferred), &result);
787 } else {
788 napi_get_undefined(env, &result);
789 }
790
791 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMap",
792 CreatePixelMapExec, CreatePixelMapComplete, asyncContext, asyncContext->work);
793
794 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
795 nullptr, IMAGE_LOGE("fail to create async work"));
796 return result;
797 }
798
799 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
STATIC_EXEC_FUNC(CreatePixelMapFromSurface)800 STATIC_EXEC_FUNC(CreatePixelMapFromSurface)
801 {
802 auto context = static_cast<PixelMapAsyncContext*>(data);
803 IMAGE_LOGD("CreatePixelMapFromSurface id:%{public}s,area:%{public}d,%{public}d,%{public}d,%{public}d",
804 context->surfaceId.c_str(), context->area.region.left, context->area.region.top,
805 context->area.region.height, context->area.region.width);
806
807 auto pixelMap = CreatePixelMapFromSurfaceId(std::stoull(context->surfaceId), context->area.region);
808 context->rPixelMap = std::move(pixelMap);
809
810 if (IMG_NOT_NULL(context->rPixelMap)) {
811 context->status = SUCCESS;
812 } else {
813 context->status = ERR_IMAGE_INVALID_PARAMETER;
814 }
815 }
816
CreatePixelMapFromSurfaceComplete(napi_env env,napi_status status,void * data)817 void PixelMapNapi::CreatePixelMapFromSurfaceComplete(napi_env env, napi_status status, void *data)
818 {
819 napi_value constructor = nullptr;
820 napi_value result = nullptr;
821
822 IMAGE_LOGD("CreatePixelMapFromSurface IN");
823 auto context = static_cast<PixelMapAsyncContext*>(data);
824 status = napi_get_reference_value(env, sConstructor_, &constructor);
825 if (IMG_IS_OK(status)) {
826 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
827 }
828
829 if (!IMG_IS_OK(status)) {
830 context->status = ERR_IMAGE_PIXELMAP_CREATE_FAILED;
831 IMAGE_LOGE("New instance could not be obtained");
832 napi_get_undefined(env, &result);
833 }
834
835 CommonCallbackRoutine(env, context, result);
836 }
837
setSurfaceId(const char * surfaceId,std::string & dst)838 void setSurfaceId(const char *surfaceId, std::string &dst)
839 {
840 dst = surfaceId;
841 }
842
GetStringArgument(napi_env env,napi_value value)843 static std::string GetStringArgument(napi_env env, napi_value value)
844 {
845 std::string strValue = "";
846 size_t bufLength = 0;
847 napi_status status = napi_get_value_string_utf8(env, value, nullptr, NUM_0, &bufLength);
848 if (status == napi_ok && bufLength > NUM_0 && bufLength < PATH_MAX) {
849 char *buffer = reinterpret_cast<char *>(malloc((bufLength + NUM_1) * sizeof(char)));
850 if (buffer == nullptr) {
851 IMAGE_LOGE("No memory");
852 return strValue;
853 }
854
855 status = napi_get_value_string_utf8(env, value, buffer, bufLength + NUM_1, &bufLength);
856 if (status == napi_ok) {
857 IMAGE_LOGD("Get Success");
858 strValue.assign(buffer, 0, bufLength + NUM_1);
859 }
860 if (buffer != nullptr) {
861 free(buffer);
862 buffer = nullptr;
863 }
864 }
865 return strValue;
866 }
867
CreatePixelMapFromSurface(napi_env env,napi_callback_info info)868 napi_value PixelMapNapi::CreatePixelMapFromSurface(napi_env env, napi_callback_info info)
869 {
870 napi_value globalValue;
871 napi_get_global(env, &globalValue);
872 napi_value func;
873 napi_get_named_property(env, globalValue, "requireNapi", &func);
874
875 napi_value imageInfo;
876 napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
877 napi_value funcArgv[1] = { imageInfo };
878 napi_value returnValue;
879 napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
880
881 napi_value result = nullptr;
882 napi_get_undefined(env, &result);
883 int32_t refCount = 1;
884 napi_status status;
885 napi_value thisVar = nullptr;
886 napi_value argValue[NUM_4] = {0};
887 size_t argCount = NUM_4;
888 IMAGE_LOGD("CreatePixelMapFromSurface IN");
889 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
890 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
891 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
892 asyncContext->surfaceId = GetStringArgument(env, argValue[NUM_0]);
893 bool ret = parseRegion(env, argValue[NUM_1], &(asyncContext->area.region));
894 IMAGE_LOGD("CreatePixelMapFromSurface get data: %{public}d", ret);
895 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
896 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
897 }
898 if (asyncContext->callbackRef == nullptr) {
899 napi_create_promise(env, &(asyncContext->deferred), &result);
900 } else {
901 napi_get_undefined(env, &result);
902 }
903 IMG_NAPI_CHECK_BUILD_ERROR(ret,
904 BuildContextError(env, asyncContext->error, "image invalid parameter", ERR_IMAGE_GET_DATA_ABNORMAL),
905 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMapFromSurfaceGeneralError",
906 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
907 result);
908 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMapFromSurface",
909 CreatePixelMapFromSurfaceExec, CreatePixelMapFromSurfaceComplete, asyncContext, asyncContext->work);
910 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
911 nullptr, IMAGE_LOGE("fail to create async work"));
912 return result;
913 }
914 #endif
915
CreatePixelMap(napi_env env,std::shared_ptr<PixelMap> pixelmap)916 napi_value PixelMapNapi::CreatePixelMap(napi_env env, std::shared_ptr<PixelMap> pixelmap)
917 {
918 if (PixelMapNapi::GetConstructor() == nullptr) {
919 napi_value exports = nullptr;
920 napi_create_object(env, &exports);
921 PixelMapNapi::Init(env, exports);
922 }
923
924 napi_value constructor = nullptr;
925 napi_value result = nullptr;
926 napi_status status;
927
928 IMAGE_LOGD("CreatePixelMap IN");
929 status = napi_get_reference_value(env, sConstructor_, &constructor);
930
931 if (IMG_IS_OK(status)) {
932 status = NewPixelNapiInstance(env, constructor, pixelmap, result);
933 }
934
935 if (!IMG_IS_OK(status)) {
936 IMAGE_LOGE("CreatePixelMap | New instance could not be obtained");
937 napi_get_undefined(env, &result);
938 }
939
940 return result;
941 }
942
STATIC_EXEC_FUNC(Unmarshalling)943 STATIC_EXEC_FUNC(Unmarshalling)
944 {
945 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
946 auto context = static_cast<PixelMapAsyncContext*>(data);
947
948 auto messageParcel = napi_messageSequence->GetMessageParcel();
949 auto pixelmap = PixelMap::Unmarshalling(*messageParcel);
950 std::unique_ptr<OHOS::Media::PixelMap> pixelmap_ptr(pixelmap);
951
952 context->rPixelMap = std::move(pixelmap_ptr);
953
954 if (IMG_NOT_NULL(context->rPixelMap)) {
955 context->status = SUCCESS;
956 } else {
957 context->status = ERROR;
958 }
959 #endif
960 }
961
UnmarshallingComplete(napi_env env,napi_status status,void * data)962 void PixelMapNapi::UnmarshallingComplete(napi_env env, napi_status status, void *data)
963 {
964 napi_value constructor = nullptr;
965 napi_value result = nullptr;
966
967 IMAGE_LOGD("UnmarshallingComplete IN");
968 auto context = static_cast<PixelMapAsyncContext*>(data);
969
970 status = napi_get_reference_value(env, sConstructor_, &constructor);
971 if (IMG_IS_OK(status)) {
972 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
973 }
974
975 if (!IMG_IS_OK(status)) {
976 context->status = ERROR;
977 IMAGE_LOGE("New instance could not be obtained");
978 napi_get_undefined(env, &result);
979 }
980
981 CommonCallbackRoutine(env, context, result);
982 }
983
Unmarshalling(napi_env env,napi_callback_info info)984 napi_value PixelMapNapi::Unmarshalling(napi_env env, napi_callback_info info)
985 {
986 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
987 if (PixelMapNapi::GetConstructor() == nullptr) {
988 napi_value exports = nullptr;
989 napi_create_object(env, &exports);
990 PixelMapNapi::Init(env, exports);
991 }
992 napi_value result = nullptr;
993 napi_get_undefined(env, &result);
994
995 int32_t refCount = 1;
996
997 napi_status status;
998 napi_value thisVar = nullptr;
999 napi_value argValue[NUM_4] = {0};
1000 size_t argCount = NUM_4;
1001 IMAGE_LOGD("Unmarshalling IN");
1002
1003 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1004
1005 // we are static method!
1006 // thisVar is nullptr here
1007 if (!IMG_IS_OK(status)) {
1008 return ImageNapiUtils::ThrowExceptionError(
1009 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to napi_get_cb_info");
1010 }
1011 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1012
1013 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1014 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1015 }
1016
1017 napi_unwrap(env, argValue[NUM_0], (void **)&napi_messageSequence);
1018
1019 if (asyncContext->callbackRef == nullptr) {
1020 napi_create_promise(env, &(asyncContext->deferred), &result);
1021 } else {
1022 napi_get_undefined(env, &result);
1023 }
1024
1025 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "Unmarshalling",
1026 UnmarshallingExec, UnmarshallingComplete, asyncContext, asyncContext->work);
1027
1028 if (!IMG_IS_OK(status)) {
1029 return ImageNapiUtils::ThrowExceptionError(
1030 env, ERROR, "Fail to create async work");
1031 }
1032 return result;
1033 #else
1034 napi_value result = nullptr;
1035 return result;
1036 #endif
1037 }
1038
ThrowExceptionError(napi_env env,const std::string & tag,const std::uint32_t & code,const std::string & info)1039 napi_value PixelMapNapi::ThrowExceptionError(napi_env env,
1040 const std::string &tag, const std::uint32_t &code, const std::string &info)
1041 {
1042 auto errNode = ETS_API_ERROR_CODE.find(tag);
1043 if (errNode != ETS_API_ERROR_CODE.end() &&
1044 errNode->second.find(code) != errNode->second.end()) {
1045 return ImageNapiUtils::ThrowExceptionError(env, code, info);
1046 }
1047 return ImageNapiUtils::ThrowExceptionError(env, ERROR, "Operation failed");
1048 }
1049
CreatePixelMapFromParcel(napi_env env,napi_callback_info info)1050 napi_value PixelMapNapi::CreatePixelMapFromParcel(napi_env env, napi_callback_info info)
1051 #if defined(IOS_PLATFORM) || defined(A_PLATFORM)
1052 {
1053 napi_value result = nullptr;
1054 return result;
1055 }
1056 #else
1057 {
1058 if (PixelMapNapi::GetConstructor() == nullptr) {
1059 napi_value exports = nullptr;
1060 napi_create_object(env, &exports);
1061 PixelMapNapi::Init(env, exports);
1062 }
1063 napi_value result = nullptr;
1064 napi_get_undefined(env, &result);
1065 napi_status status;
1066 napi_value thisVar = nullptr;
1067 napi_value argValue[NUM_1] = {0};
1068 size_t argCount = NUM_1;
1069 IMAGE_LOGD("CreatePixelMapFromParcel IN");
1070 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1071 if (!IMG_IS_OK(status) || argCount != NUM_1) {
1072 return PixelMapNapi::ThrowExceptionError(env,
1073 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IMAGE_INVALID_PARAMETER, "Fail to napi_get_cb_info");
1074 }
1075 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1076 napi_unwrap(env, argValue[NUM_0], (void **)&napi_messageSequence);
1077 auto messageParcel = napi_messageSequence->GetMessageParcel();
1078 if (messageParcel == nullptr) {
1079 return PixelMapNapi::ThrowExceptionError(env,
1080 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IPC, "get pacel failed");
1081 }
1082 PIXEL_MAP_ERR error;
1083 auto pixelmap = PixelMap::Unmarshalling(*messageParcel, error);
1084 if (!IMG_NOT_NULL(pixelmap)) {
1085 return PixelMapNapi::ThrowExceptionError(env,
1086 CREATE_PIXEL_MAP_FROM_PARCEL, error.errorCode, error.errorInfo);
1087 }
1088 std::shared_ptr<OHOS::Media::PixelMap> pixelPtr(pixelmap);
1089 napi_value constructor = nullptr;
1090 status = napi_get_reference_value(env, sConstructor_, &constructor);
1091 if (IMG_IS_OK(status)) {
1092 status = NewPixelNapiInstance(env, constructor, pixelPtr, result);
1093 }
1094 if (!IMG_IS_OK(status)) {
1095 IMAGE_LOGE("New instance could not be obtained");
1096 return PixelMapNapi::ThrowExceptionError(env,
1097 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IMAGE_NAPI_ERROR, "New instance could not be obtained");
1098 }
1099 return result;
1100 }
1101 #endif
1102
GetIsEditable(napi_env env,napi_callback_info info)1103 napi_value PixelMapNapi::GetIsEditable(napi_env env, napi_callback_info info)
1104 {
1105 napi_value result = nullptr;
1106 napi_get_undefined(env, &result);
1107
1108 napi_status status;
1109 napi_value thisVar = nullptr;
1110 size_t argCount = 0;
1111 IMAGE_LOGD("GetIsEditable IN");
1112
1113 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1114
1115 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1116
1117 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1118 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1119
1120 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1121
1122 if (pixelMapNapi->nativePixelMap_ == nullptr) {
1123 return result;
1124 }
1125 bool isEditable = pixelMapNapi->nativePixelMap_->IsEditable();
1126
1127 napi_get_boolean(env, isEditable, &result);
1128 pixelMapNapi.release();
1129
1130 return result;
1131 }
1132
GetIsStrideAlignment(napi_env env,napi_callback_info info)1133 napi_value PixelMapNapi::GetIsStrideAlignment(napi_env env, napi_callback_info info)
1134 {
1135 napi_value result = nullptr;
1136 napi_get_undefined(env, &result);
1137
1138 napi_status status;
1139 napi_value thisVar = nullptr;
1140 size_t argCount = 0;
1141 IMAGE_LOGD("GetIsStrideAlignment IN");
1142
1143 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1144
1145 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1146
1147 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1148 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1149
1150 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi),
1151 result, IMAGE_LOGE("fail to unwrap context"));
1152
1153 if (pixelMapNapi->nativePixelMap_ == nullptr) {
1154 return result;
1155 }
1156 bool isDMA = pixelMapNapi->nativePixelMap_->IsStrideAlignment();
1157 napi_get_boolean(env, isDMA, &result);
1158 pixelMapNapi.release();
1159 return result;
1160 }
1161
ReadPixelsToBuffer(napi_env env,napi_callback_info info)1162 napi_value PixelMapNapi::ReadPixelsToBuffer(napi_env env, napi_callback_info info)
1163 {
1164 ImageTrace imageTrace("PixelMapNapi::ReadPixelsToBuffer");
1165 napi_value result = nullptr;
1166 napi_get_undefined(env, &result);
1167
1168 int32_t refCount = 1;
1169 napi_status status;
1170 napi_value thisVar = nullptr;
1171 napi_value argValue[NUM_2] = {0};
1172 size_t argCount = NUM_2;
1173
1174 IMAGE_LOGD("ReadPixelsToBuffer IN");
1175 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1176
1177 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1178
1179 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1180 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1181
1182 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1183 nullptr, IMAGE_LOGE("fail to unwrap context"));
1184 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1185
1186 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1187 nullptr, IMAGE_LOGE("empty native pixelmap"));
1188
1189 status = napi_get_arraybuffer_info(env, argValue[NUM_0],
1190 &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
1191
1192 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
1193
1194 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1195 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1196 }
1197
1198 if (asyncContext->callbackRef == nullptr) {
1199 napi_create_promise(env, &(asyncContext->deferred), &result);
1200 } else {
1201 napi_get_undefined(env, &result);
1202 }
1203
1204 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1205 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . ReadPixelsToBuffer failed",
1206 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsToBufferGeneralError",
1207 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1208 result);
1209 IMG_CREATE_CREATE_ASYNC_WORK_WITH_QOS(env, status, "ReadPixelsToBuffer",
1210 [](napi_env env, void *data)
1211 {
1212 auto context = static_cast<PixelMapAsyncContext*>(data);
1213 context->status = context->rPixelMap->ReadPixels(
1214 context->colorsBufferSize, static_cast<uint8_t*>(context->colorsBuffer));
1215 }, EmptyResultComplete, asyncContext, asyncContext->work, napi_qos_user_initiated);
1216
1217 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1218 nullptr, IMAGE_LOGE("fail to create async work"));
1219 return result;
1220 }
1221
ReadPixels(napi_env env,napi_callback_info info)1222 napi_value PixelMapNapi::ReadPixels(napi_env env, napi_callback_info info)
1223 {
1224 napi_value result = nullptr;
1225 napi_get_undefined(env, &result);
1226
1227 int32_t refCount = 1;
1228 napi_status status;
1229 napi_value thisVar = nullptr;
1230 napi_value argValue[NUM_2] = {0};
1231 size_t argCount = NUM_2;
1232
1233 IMAGE_LOGD("ReadPixels IN");
1234 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1235
1236 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1237
1238 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1239 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1240
1241 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1242 nullptr, IMAGE_LOGE("fail to unwrap context"));
1243
1244 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1245
1246 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1247 nullptr, IMAGE_LOGE("empty native pixelmap"));
1248
1249 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
1250 nullptr, IMAGE_LOGE("fail to parse position area"));
1251
1252 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1253 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1254 }
1255
1256 if (asyncContext->callbackRef == nullptr) {
1257 napi_create_promise(env, &(asyncContext->deferred), &result);
1258 } else {
1259 napi_get_undefined(env, &result);
1260 }
1261
1262 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1263 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . ReadPixels failed",
1264 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsGeneralError",
1265 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1266 result);
1267 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixels",
1268 [](napi_env env, void *data)
1269 {
1270 auto context = static_cast<PixelMapAsyncContext*>(data);
1271 auto area = context->area;
1272 context->status = context->rPixelMap->ReadPixels(
1273 area.size, area.offset, area.stride, area.region, static_cast<uint8_t*>(area.pixels));
1274 }, EmptyResultComplete, asyncContext, asyncContext->work);
1275
1276 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1277 nullptr, IMAGE_LOGE("fail to create async work"));
1278 return result;
1279 }
1280
WritePixels(napi_env env,napi_callback_info info)1281 napi_value PixelMapNapi::WritePixels(napi_env env, napi_callback_info info)
1282 {
1283 napi_value result = nullptr;
1284 napi_get_undefined(env, &result);
1285
1286 int32_t refCount = 1;
1287 napi_status status;
1288 napi_value thisVar = nullptr;
1289 napi_value argValue[NUM_2] = {0};
1290 size_t argCount = NUM_2;
1291
1292 IMAGE_LOGD("WritePixels IN");
1293 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1294
1295 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1296
1297 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1298 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1299
1300 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1301 nullptr, IMAGE_LOGE("fail to unwrap context"));
1302 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1303
1304 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1305 nullptr, IMAGE_LOGE("empty native pixelmap"));
1306
1307 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
1308 nullptr, IMAGE_LOGE("fail to parse position area"));
1309
1310 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1311 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1312 }
1313
1314 if (asyncContext->callbackRef == nullptr) {
1315 napi_create_promise(env, &(asyncContext->deferred), &result);
1316 } else {
1317 napi_get_undefined(env, &result);
1318 }
1319 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1320 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . WritePixels failed",
1321 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WritePixelsGeneralError",
1322 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1323 result);
1324 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WritePixels",
1325 [](napi_env env, void *data)
1326 {
1327 auto context = static_cast<PixelMapAsyncContext*>(data);
1328 auto area = context->area;
1329 context->status = context->rPixelMap->WritePixels(
1330 static_cast<uint8_t*>(area.pixels), area.size, area.offset, area.stride, area.region);
1331 }, EmptyResultComplete, asyncContext, asyncContext->work);
1332
1333 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1334 nullptr, IMAGE_LOGE("fail to create async work"));
1335 return result;
1336 }
1337
WriteBufferToPixels(napi_env env,napi_callback_info info)1338 napi_value PixelMapNapi::WriteBufferToPixels(napi_env env, napi_callback_info info)
1339 {
1340 ImageTrace imageTrace("PixelMapNapi::WriteBufferToPixels");
1341 napi_value result = nullptr;
1342 napi_get_undefined(env, &result);
1343
1344 int32_t refCount = 1;
1345 napi_status status;
1346 napi_value thisVar = nullptr;
1347 napi_value argValue[NUM_2] = {0};
1348 size_t argCount = NUM_2;
1349
1350 IMAGE_LOGD("WriteBufferToPixels IN");
1351 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1352
1353 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1354
1355 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1356 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1357
1358 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1359 nullptr, IMAGE_LOGE("fail to unwrap context"));
1360 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1361
1362 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1363 nullptr, IMAGE_LOGE("empty native pixelmap"));
1364 status = napi_get_arraybuffer_info(env, argValue[NUM_0],
1365 &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
1366
1367 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1368 nullptr, IMAGE_LOGE("fail to get buffer info"));
1369
1370 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1371 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1372 }
1373
1374 if (asyncContext->callbackRef == nullptr) {
1375 napi_create_promise(env, &(asyncContext->deferred), &result);
1376 } else {
1377 napi_get_undefined(env, &result);
1378 }
1379 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1380 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . WriteBufferToPixels failed",
1381 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WriteBufferToPixelsGeneralError",
1382 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1383 result);
1384 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WriteBufferToPixels",
1385 [](napi_env env, void *data)
1386 {
1387 auto context = static_cast<PixelMapAsyncContext*>(data);
1388 context->status = context->rPixelMap->WritePixels(static_cast<uint8_t*>(context->colorsBuffer),
1389 context->colorsBufferSize);
1390 }, EmptyResultComplete, asyncContext, asyncContext->work);
1391
1392 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1393 nullptr, IMAGE_LOGE("fail to create async work"));
1394 return result;
1395 }
1396
STATIC_COMPLETE_FUNC(GetImageInfo)1397 STATIC_COMPLETE_FUNC(GetImageInfo)
1398 {
1399 IMAGE_LOGD("[PixelMap]GetImageInfoComplete IN");
1400 napi_value result = nullptr;
1401 napi_create_object(env, &result);
1402 auto context = static_cast<PixelMapAsyncContext*>(data);
1403 napi_value size = nullptr;
1404 napi_create_object(env, &size);
1405 napi_value sizeWith = nullptr;
1406 napi_create_int32(env, context->imageInfo.size.width, &sizeWith);
1407 napi_set_named_property(env, size, "width", sizeWith);
1408 napi_value sizeHeight = nullptr;
1409 napi_create_int32(env, context->imageInfo.size.height, &sizeHeight);
1410 napi_set_named_property(env, size, "height", sizeHeight);
1411 napi_set_named_property(env, result, "size", size);
1412 napi_value pixelFormatValue = nullptr;
1413 napi_create_int32(env, static_cast<int32_t>(context->imageInfo.pixelFormat), &pixelFormatValue);
1414 napi_set_named_property(env, result, "pixelFormat", pixelFormatValue);
1415 napi_value colorSpaceValue = nullptr;
1416 napi_create_int32(env, static_cast<int32_t>(context->imageInfo.colorSpace), &colorSpaceValue);
1417 napi_set_named_property(env, result, "colorSpace", colorSpaceValue);
1418 napi_value alphaTypeValue = nullptr;
1419 napi_create_int32(env, static_cast<int32_t>(context->imageInfo.alphaType), &alphaTypeValue);
1420 napi_set_named_property(env, result, "alphaType", alphaTypeValue);
1421 napi_value densityValue = nullptr;
1422 napi_create_int32(env, static_cast<int32_t>(context->imageInfo.baseDensity), &densityValue);
1423 napi_set_named_property(env, result, "density", densityValue);
1424 napi_value strideValue = nullptr;
1425 napi_create_int32(env, static_cast<int32_t>(context->rPixelMap->GetRowStride()), &strideValue);
1426 napi_set_named_property(env, result, "stride", strideValue);
1427 if (!IMG_IS_OK(status)) {
1428 context->status = ERROR;
1429 IMAGE_LOGE("napi_create_int32 failed!");
1430 napi_get_undefined(env, &result);
1431 } else {
1432 context->status = SUCCESS;
1433 }
1434 IMAGE_LOGD("[PixelMap]GetImageInfoComplete OUT");
1435 CommonCallbackRoutine(env, context, result);
1436 }
GetImageInfo(napi_env env,napi_callback_info info)1437 napi_value PixelMapNapi::GetImageInfo(napi_env env, napi_callback_info info)
1438 {
1439 napi_value result = nullptr;
1440 napi_get_undefined(env, &result);
1441 int32_t refCount = 1;
1442 napi_status status;
1443 napi_value thisVar = nullptr;
1444 napi_value argValue[NUM_1] = {0};
1445 size_t argCount = 1;
1446 IMAGE_LOGD("GetImageInfo IN");
1447 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1448 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1449 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1450 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1451 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1452 nullptr, IMAGE_LOGE("fail to unwrap context"));
1453 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1454 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1455 nullptr, IMAGE_LOGE("empty native pixelmap"));
1456 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1457 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1458 }
1459 if (asyncContext->callbackRef == nullptr) {
1460 napi_create_promise(env, &(asyncContext->deferred), &result);
1461 } else {
1462 napi_get_undefined(env, &result);
1463 }
1464 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1465 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . GetImageInfo failed",
1466 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfoGeneralError",
1467 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1468 result);
1469 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfo",
1470 [](napi_env env, void *data)
1471 {
1472 auto context = static_cast<PixelMapAsyncContext*>(data);
1473 context->rPixelMap->GetImageInfo(context->imageInfo);
1474 context->status = SUCCESS;
1475 }, GetImageInfoComplete, asyncContext, asyncContext->work);
1476 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1477 nullptr, IMAGE_LOGE("fail to create async work"));
1478 return result;
1479 }
1480
GetBytesNumberPerRow(napi_env env,napi_callback_info info)1481 napi_value PixelMapNapi::GetBytesNumberPerRow(napi_env env, napi_callback_info info)
1482 {
1483 ImageTrace imageTrace("PixelMapNapi::GetBytesNumberPerRow");
1484 napi_value result = nullptr;
1485 napi_get_undefined(env, &result);
1486
1487 napi_status status;
1488 napi_value thisVar = nullptr;
1489 size_t argCount = 0;
1490
1491 IMAGE_LOGD("GetBytesNumberPerRow IN");
1492 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1493
1494 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1495
1496 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1497 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1498
1499 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1500 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1501 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1502 "Pixelmap has crossed threads . GetBytesNumberPerRow failed"),
1503 IMAGE_LOGE("Pixelmap has crossed threads . GetBytesNumberPerRow failed"));
1504
1505 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1506 uint32_t rowBytes = pixelMapNapi->nativePixelMap_->GetRowBytes();
1507 status = napi_create_int32(env, rowBytes, &result);
1508 if (!IMG_IS_OK(status)) {
1509 IMAGE_LOGE("napi_create_int32 failed!");
1510 }
1511 } else {
1512 IMAGE_LOGE("native pixelmap is nullptr!");
1513 }
1514 pixelMapNapi.release();
1515 return result;
1516 }
1517
GetPixelBytesNumber(napi_env env,napi_callback_info info)1518 napi_value PixelMapNapi::GetPixelBytesNumber(napi_env env, napi_callback_info info)
1519 {
1520 ImageTrace imageTrace("PixelMapNapi::GetPixelBytesNumber");
1521 napi_value result = nullptr;
1522 napi_get_undefined(env, &result);
1523
1524 napi_status status;
1525 napi_value thisVar = nullptr;
1526 size_t argCount = 0;
1527
1528 IMAGE_LOGD("GetPixelBytesNumber IN");
1529 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1530
1531 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1532
1533 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1534 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1535
1536 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1537 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1538 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1539 "Pixelmap has crossed threads . GetPixelBytesNumber failed"),
1540 IMAGE_LOGE("Pixelmap has crossed threads . GetPixelBytesNumber failed"));
1541
1542 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1543 uint32_t byteCount = pixelMapNapi->nativePixelMap_->GetByteCount();
1544 status = napi_create_int32(env, byteCount, &result);
1545 if (!IMG_IS_OK(status)) {
1546 IMAGE_LOGE("napi_create_int32 failed!");
1547 }
1548 } else {
1549 IMAGE_LOGE("native pixelmap is nullptr!");
1550 }
1551 pixelMapNapi.release();
1552 return result;
1553 }
1554
IsSupportAlpha(napi_env env,napi_callback_info info)1555 napi_value PixelMapNapi::IsSupportAlpha(napi_env env, napi_callback_info info)
1556 {
1557 napi_value result = nullptr;
1558 napi_get_undefined(env, &result);
1559
1560 napi_status status;
1561 napi_value thisVar = nullptr;
1562 size_t argCount = NUM_0;
1563
1564 IMAGE_LOGD("IsSupportAlpha IN");
1565 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1566
1567 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1568
1569 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1570 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1571
1572 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1573 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1574 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1575 "Pixelmap has crossed threads . IsSupportAlpha failed"),
1576 IMAGE_LOGE("Pixelmap has crossed threads . IsSupportAlpha failed"));
1577
1578 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1579 AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
1580 bool isSupportAlpha = !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
1581 status = napi_get_boolean(env, isSupportAlpha, &result);
1582 if (!IMG_IS_OK(status)) {
1583 IMAGE_LOGE("napi_create_bool failed!");
1584 }
1585 } else {
1586 IMAGE_LOGE("native pixelmap is nullptr!");
1587 }
1588 pixelMapNapi.release();
1589 return result;
1590 }
1591
SetAlphaAble(napi_env env,napi_callback_info info)1592 napi_value PixelMapNapi::SetAlphaAble(napi_env env, napi_callback_info info)
1593 {
1594 napi_value result = nullptr;
1595 napi_get_undefined(env, &result);
1596
1597 napi_status status;
1598 napi_value thisVar = nullptr;
1599 napi_value argValue[NUM_1] = {0};
1600 size_t argCount = NUM_1;
1601 bool isAlphaAble = false;
1602
1603 IMAGE_LOGD("SetAlphaAble IN");
1604 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1605
1606 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1607 NAPI_ASSERT(env, argCount > NUM_0, "Invalid input");
1608 NAPI_ASSERT(env, ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_boolean, "Invalid input type");
1609 NAPI_ASSERT(env, napi_get_value_bool(env, argValue[NUM_0], &isAlphaAble) == napi_ok, "Parse input error");
1610
1611 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1612 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1613
1614 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1615 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1616 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1617 "Pixelmap has crossed threads . SetAlphaAble failed"),
1618 IMAGE_LOGE("Pixelmap has crossed threads . SetAlphaAble failed"));
1619 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1620 AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
1621 if (isAlphaAble && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1622 pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
1623 } else if ((!isAlphaAble) && !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1624 pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
1625 }
1626 } else {
1627 IMAGE_LOGE("native pixelmap is nullptr!");
1628 }
1629 pixelMapNapi.release();
1630 return result;
1631 }
1632
CreateAlphaPixelmapComplete(napi_env env,napi_status status,void * data)1633 static void CreateAlphaPixelmapComplete(napi_env env, napi_status status, void *data)
1634 {
1635 napi_value result = nullptr;
1636 napi_get_undefined(env, &result);
1637 auto context = static_cast<PixelMapAsyncContext*>(data);
1638
1639 if (context->alphaMap != nullptr) {
1640 result = PixelMapNapi::CreatePixelMap(env, context->alphaMap);
1641 context->status = SUCCESS;
1642 } else {
1643 context->status = ERROR;
1644 }
1645 CommonCallbackRoutine(env, context, result);
1646 }
1647
CreateAlphaPixelmap(napi_env env,napi_callback_info info)1648 napi_value PixelMapNapi::CreateAlphaPixelmap(napi_env env, napi_callback_info info)
1649 {
1650 napi_value result = nullptr;
1651 napi_get_undefined(env, &result);
1652 int32_t refCount = 1;
1653 napi_status status;
1654 napi_value thisVar = nullptr;
1655 napi_value argValue[NUM_1] = {0};
1656 size_t argCount = 1;
1657 IMAGE_LOGD("CreateAlphaPixelmap IN");
1658 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1659 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1660 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1661 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1662 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1663 nullptr, IMAGE_LOGE("fail to unwrap context"));
1664 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1665 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1666 nullptr, IMAGE_LOGE("empty native pixelmap"));
1667 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1668 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1669 }
1670 if (asyncContext->callbackRef == nullptr) {
1671 napi_create_promise(env, &(asyncContext->deferred), &result);
1672 } else {
1673 napi_get_undefined(env, &result);
1674 }
1675 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1676 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . CreateAlphaPixelmap failed",
1677 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateAlphaPixelmapGeneralError",
1678 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1679 result);
1680 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateAlphaPixelmap",
1681 [](napi_env env, void *data)
1682 {
1683 auto context = static_cast<PixelMapAsyncContext*>(data);
1684 InitializationOptions opts;
1685 opts.pixelFormat = PixelFormat::ALPHA_8;
1686 auto tmpPixelMap = PixelMap::Create(*(context->rPixelMap), opts);
1687 context->alphaMap = std::move(tmpPixelMap);
1688 context->status = SUCCESS;
1689 }, CreateAlphaPixelmapComplete, asyncContext, asyncContext->work);
1690 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1691 nullptr, IMAGE_LOGE("fail to create async work"));
1692 return result;
1693 }
1694
GetDensity(napi_env env,napi_callback_info info)1695 napi_value PixelMapNapi::GetDensity(napi_env env, napi_callback_info info)
1696 {
1697 napi_value result = nullptr;
1698 napi_get_undefined(env, &result);
1699
1700 napi_status status;
1701 napi_value thisVar = nullptr;
1702 size_t argCount = 0;
1703
1704 IMAGE_LOGD("GetDensity IN");
1705 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1706
1707 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1708
1709 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1710 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1711
1712 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1713 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1714 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1715 "Pixelmap has crossed threads . GetDensity failed"),
1716 IMAGE_LOGE("Pixelmap has crossed threads . GetDensity failed"));
1717
1718 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1719 uint32_t baseDensity = pixelMapNapi->nativePixelMap_->GetBaseDensity();
1720 status = napi_create_int32(env, baseDensity, &result);
1721 if (!IMG_IS_OK(status)) {
1722 IMAGE_LOGE("napi_create_int32 failed!");
1723 }
1724 } else {
1725 IMAGE_LOGE("native pixelmap is nullptr!");
1726 }
1727 pixelMapNapi.release();
1728 return result;
1729 }
1730
SetDensity(napi_env env,napi_callback_info info)1731 napi_value PixelMapNapi::SetDensity(napi_env env, napi_callback_info info)
1732 {
1733 napi_value result = nullptr;
1734 napi_get_undefined(env, &result);
1735
1736 napi_status status;
1737 napi_value thisVar = nullptr;
1738 napi_value argValue[NUM_1] = {0};
1739 size_t argCount = NUM_1;
1740 uint32_t density = 0;
1741
1742 IMAGE_LOGD("SetDensity IN");
1743 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1744 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1745
1746 NAPI_ASSERT(env,
1747 (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number),
1748 "Density input mismatch");
1749 NAPI_ASSERT(env, napi_get_value_uint32(env, argValue[NUM_0], &density) == napi_ok, "Could not parse density");
1750
1751 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1752 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1753
1754 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1755 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1756 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1757 "Pixelmap has crossed threads . SetDensity failed"),
1758 IMAGE_LOGE("Pixelmap has crossed threads . SetDensity failed"));
1759 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1760 ImageInfo imageinfo;
1761 pixelMapNapi->nativePixelMap_->GetImageInfo(imageinfo);
1762 imageinfo.baseDensity = density;
1763 pixelMapNapi->nativePixelMap_->SetImageInfo(imageinfo, true);
1764 } else {
1765 IMAGE_LOGE("native pixelmap is nullptr!");
1766 }
1767 pixelMapNapi.release();
1768 return result;
1769 }
1770
Release(napi_env env,napi_callback_info info)1771 napi_value PixelMapNapi::Release(napi_env env, napi_callback_info info)
1772 {
1773 napi_value result = nullptr;
1774 napi_get_undefined(env, &result);
1775
1776 int32_t refCount = 1;
1777 napi_status status;
1778 napi_value thisVar = nullptr;
1779 napi_value argValue[1] = {0};
1780 size_t argCount = 1;
1781
1782 IMAGE_LOGD("Release IN");
1783 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1784
1785 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1786
1787 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1788 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1789
1790 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1791 nullptr, IMAGE_LOGE("fail to unwrap context"));
1792
1793 if (argCount == 1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1794 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1795 }
1796
1797 if (asyncContext->callbackRef == nullptr) {
1798 napi_create_promise(env, &(asyncContext->deferred), &result);
1799 } else {
1800 napi_get_undefined(env, &result);
1801 }
1802 if (asyncContext->nConstructor->IsLockPixelMap()) {
1803 asyncContext->status = ERROR;
1804 } else {
1805 if (asyncContext->nConstructor->nativePixelMap_ != nullptr) {
1806 IMAGE_LOGD("Release in napi_id:%{public}d, id:%{public}d",
1807 asyncContext->nConstructor->GetUniqueId(),
1808 asyncContext->nConstructor->nativePixelMap_->GetUniqueId());
1809 asyncContext->nConstructor->nativePixelMap_.reset();
1810 }
1811 asyncContext->status = SUCCESS;
1812 }
1813 IMG_CREATE_CREATE_ASYNC_WORK_WITH_QOS(env, status, "Release",
1814 [](napi_env env, void *data)
1815 {
1816 uint32_t executeId = static_cast<uint32_t>(ImageNapiUtils::GetNowTimeMicroSeconds());
1817 IMAGE_LOGI("PixelMap Release, id: %{public}u", executeId);
1818 }, EmptyResultComplete, asyncContext, asyncContext->work, napi_qos_user_initiated);
1819
1820 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1821 nullptr, IMAGE_LOGE("fail to create async work"));
1822 return result;
1823 }
1824
1825 struct NapiValues {
1826 napi_status status;
1827 napi_value thisVar = nullptr;
1828 napi_value result = nullptr;
1829 napi_value* argv = nullptr;
1830 size_t argc;
1831 int32_t refCount = 1;
1832 std::unique_ptr<PixelMapAsyncContext> context;
1833 };
1834
prepareNapiEnv(napi_env env,napi_callback_info info,struct NapiValues * nVal)1835 static bool prepareNapiEnv(napi_env env, napi_callback_info info, struct NapiValues* nVal)
1836 {
1837 napi_get_undefined(env, &(nVal->result));
1838 nVal->status = napi_get_cb_info(env, info, &(nVal->argc), nVal->argv, &(nVal->thisVar), nullptr);
1839 if (nVal->status != napi_ok) {
1840 IMAGE_LOGE("fail to napi_get_cb_info");
1841 return false;
1842 }
1843 nVal->context = std::make_unique<PixelMapAsyncContext>();
1844 nVal->status = napi_unwrap(env, nVal->thisVar, reinterpret_cast<void**>(&(nVal->context->nConstructor)));
1845 if (nVal->status != napi_ok) {
1846 IMAGE_LOGE("fail to unwrap context");
1847 return false;
1848 }
1849 nVal->context->status = SUCCESS;
1850 return true;
1851 }
1852
SetAlphaExec(napi_env env,PixelMapAsyncContext * context)1853 static void SetAlphaExec(napi_env env, PixelMapAsyncContext* context)
1854 {
1855 if (context == nullptr) {
1856 IMAGE_LOGE("Null context");
1857 return;
1858 }
1859 if (context->status == SUCCESS) {
1860 if (context->rPixelMap != nullptr) {
1861 context->status = context->rPixelMap->SetAlpha(
1862 static_cast<float>(context->alpha));
1863 } else {
1864 IMAGE_LOGE("Null native ref");
1865 context->status = ERR_IMAGE_INIT_ABNORMAL;
1866 }
1867 } else {
1868 IMAGE_LOGD("Scale has failed. do nothing");
1869 }
1870 }
1871
SetAlpha(napi_env env,napi_callback_info info)1872 napi_value PixelMapNapi::SetAlpha(napi_env env, napi_callback_info info)
1873 {
1874 NapiValues nVal;
1875 nVal.argc = NUM_2;
1876 napi_value argValue[NUM_2] = {0};
1877 nVal.argv = argValue;
1878
1879 IMAGE_LOGD("SetAlpha IN");
1880 if (!prepareNapiEnv(env, info, &nVal)) {
1881 return nVal.result;
1882 }
1883 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1884
1885 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
1886 IMAGE_LOGE("Invalid args count %{public}zu", nVal.argc);
1887 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1888 } else {
1889 if (napi_ok !=
1890 napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->alpha))) {
1891 IMAGE_LOGE("Arg 0 type mismatch");
1892 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1893 }
1894 }
1895 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1896 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1897 }
1898
1899 if (nVal.context->callbackRef == nullptr) {
1900 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1901 }
1902 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
1903 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . SetAlpha failed",
1904 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "SetAlphaGeneralError",
1905 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
1906 nVal.result);
1907 napi_value _resource = nullptr;
1908 napi_create_string_utf8(env, "SetAlpha", NAPI_AUTO_LENGTH, &_resource);
1909 nVal.status = napi_create_async_work(env, nullptr, _resource,
1910 [](napi_env env, void *data)
1911 {
1912 auto context = static_cast<PixelMapAsyncContext*>(data);
1913 SetAlphaExec(env, context);
1914 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1915
1916 if (nVal.status == napi_ok) {
1917 nVal.status = napi_queue_async_work(env, nVal.context->work);
1918 if (nVal.status == napi_ok) {
1919 nVal.context.release();
1920 }
1921 }
1922 return nVal.result;
1923 }
1924
ScaleExec(napi_env env,PixelMapAsyncContext * context)1925 static void ScaleExec(napi_env env, PixelMapAsyncContext* context)
1926 {
1927 if (context == nullptr) {
1928 IMAGE_LOGE("Null context");
1929 return;
1930 }
1931 if (context->status == SUCCESS) {
1932 if (context->rPixelMap != nullptr) {
1933 context->rPixelMap->scale(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
1934 context->status = SUCCESS;
1935 } else {
1936 IMAGE_LOGE("Null native ref");
1937 context->status = ERR_IMAGE_INIT_ABNORMAL;
1938 }
1939 } else {
1940 IMAGE_LOGD("Scale has failed. do nothing");
1941 }
1942 }
1943
Scale(napi_env env,napi_callback_info info)1944 napi_value PixelMapNapi::Scale(napi_env env, napi_callback_info info)
1945 {
1946 NapiValues nVal;
1947 nVal.argc = NUM_3;
1948 napi_value argValue[NUM_3] = {0};
1949 nVal.argv = argValue;
1950 IMAGE_LOGD("Scale IN");
1951 if (!prepareNapiEnv(env, info, &nVal)) {
1952 return nVal.result;
1953 }
1954 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1955
1956 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
1957 IMAGE_LOGE("Invalid args count %{public}zu", nVal.argc);
1958 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1959 } else {
1960 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
1961 IMAGE_LOGE("Arg 0 type mismatch");
1962 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1963 }
1964 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
1965 IMAGE_LOGE("Arg 1 type mismatch");
1966 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1967 }
1968 }
1969 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1970 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1971 }
1972
1973 if (nVal.context->callbackRef == nullptr) {
1974 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1975 }
1976 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
1977 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Scale failed",
1978 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "ScaleGeneralError",
1979 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
1980 nVal.result);
1981 napi_value _resource = nullptr;
1982 napi_create_string_utf8(env, "Scale", NAPI_AUTO_LENGTH, &_resource);
1983 nVal.status = napi_create_async_work(env, nullptr, _resource,
1984 [](napi_env env, void *data)
1985 {
1986 auto context = static_cast<PixelMapAsyncContext*>(data);
1987 ScaleExec(env, context);
1988 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1989
1990 if (nVal.status == napi_ok) {
1991 nVal.status = napi_queue_async_work_with_qos(env, nVal.context->work, napi_qos_user_initiated);
1992 if (nVal.status == napi_ok) {
1993 nVal.context.release();
1994 }
1995 }
1996 return nVal.result;
1997 }
1998
TranslateExec(napi_env env,PixelMapAsyncContext * context)1999 static void TranslateExec(napi_env env, PixelMapAsyncContext* context)
2000 {
2001 if (context == nullptr) {
2002 IMAGE_LOGE("Null context");
2003 return;
2004 }
2005 if (context->status == SUCCESS) {
2006 if (context->rPixelMap != nullptr) {
2007 context->rPixelMap->translate(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
2008 context->status = SUCCESS;
2009 } else {
2010 IMAGE_LOGE("Null native ref");
2011 context->status = ERR_IMAGE_INIT_ABNORMAL;
2012 }
2013 } else {
2014 IMAGE_LOGD("Translate has failed. do nothing");
2015 }
2016 }
2017
Translate(napi_env env,napi_callback_info info)2018 napi_value PixelMapNapi::Translate(napi_env env, napi_callback_info info)
2019 {
2020 NapiValues nVal;
2021 nVal.argc = NUM_3;
2022 napi_value argValue[NUM_3] = {0};
2023 nVal.argv = argValue;
2024 IMAGE_LOGD("Translate IN");
2025 if (!prepareNapiEnv(env, info, &nVal)) {
2026 return nVal.result;
2027 }
2028 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2029
2030 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
2031 IMAGE_LOGE("Invalid args count");
2032 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2033 } else {
2034 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
2035 IMAGE_LOGE("Arg 0 type mismatch");
2036 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2037 }
2038 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
2039 IMAGE_LOGE("Arg 1 type mismatch");
2040 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2041 }
2042 }
2043 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2044 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2045 }
2046
2047 if (nVal.context->callbackRef == nullptr) {
2048 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2049 }
2050 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2051 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Translate failed",
2052 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "TranslateGeneralError",
2053 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2054 nVal.result);
2055 napi_value _resource = nullptr;
2056 napi_create_string_utf8(env, "Translate", NAPI_AUTO_LENGTH, &_resource);
2057 nVal.status = napi_create_async_work(env, nullptr, _resource,
2058 [](napi_env env, void *data)
2059 {
2060 auto context = static_cast<PixelMapAsyncContext*>(data);
2061 TranslateExec(env, context);
2062 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2063
2064 if (nVal.status == napi_ok) {
2065 nVal.status = napi_queue_async_work(env, nVal.context->work);
2066 if (nVal.status == napi_ok) {
2067 nVal.context.release();
2068 }
2069 }
2070 return nVal.result;
2071 }
2072
RotateExec(napi_env env,PixelMapAsyncContext * context)2073 static void RotateExec(napi_env env, PixelMapAsyncContext* context)
2074 {
2075 if (context == nullptr) {
2076 IMAGE_LOGE("Null context");
2077 return;
2078 }
2079 if (context->status == SUCCESS) {
2080 if (context->rPixelMap != nullptr) {
2081 context->rPixelMap->rotate(context->xArg);
2082 context->status = SUCCESS;
2083 } else {
2084 IMAGE_LOGE("Null native ref");
2085 context->status = ERR_IMAGE_INIT_ABNORMAL;
2086 }
2087 } else {
2088 IMAGE_LOGD("Rotate has failed. do nothing");
2089 }
2090 }
2091
Rotate(napi_env env,napi_callback_info info)2092 napi_value PixelMapNapi::Rotate(napi_env env, napi_callback_info info)
2093 {
2094 NapiValues nVal;
2095 nVal.argc = NUM_2;
2096 napi_value argValue[NUM_2] = {0};
2097 nVal.argv = argValue;
2098 IMAGE_LOGD("Rotate IN");
2099 if (!prepareNapiEnv(env, info, &nVal)) {
2100 return nVal.result;
2101 }
2102 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2103
2104 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
2105 IMAGE_LOGE("Invalid args count");
2106 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2107 } else {
2108 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
2109 IMAGE_LOGE("Arg 0 type mismatch");
2110 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2111 }
2112 }
2113 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2114 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2115 }
2116
2117 if (nVal.context->callbackRef == nullptr) {
2118 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2119 }
2120 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2121 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Rotate failed",
2122 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "RotateGeneralError",
2123 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2124 nVal.result);
2125 napi_value _resource = nullptr;
2126 napi_create_string_utf8(env, "Rotate", NAPI_AUTO_LENGTH, &_resource);
2127 nVal.status = napi_create_async_work(env, nullptr, _resource,
2128 [](napi_env env, void *data)
2129 {
2130 auto context = static_cast<PixelMapAsyncContext*>(data);
2131 RotateExec(env, context);
2132 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2133
2134 if (nVal.status == napi_ok) {
2135 nVal.status = napi_queue_async_work(env, nVal.context->work);
2136 if (nVal.status == napi_ok) {
2137 nVal.context.release();
2138 }
2139 }
2140 return nVal.result;
2141 }
2142
FlipExec(napi_env env,PixelMapAsyncContext * context)2143 static void FlipExec(napi_env env, PixelMapAsyncContext* context)
2144 {
2145 if (context == nullptr) {
2146 IMAGE_LOGE("Null context");
2147 return;
2148 }
2149 if (context->status == SUCCESS) {
2150 if (context->rPixelMap != nullptr) {
2151 context->rPixelMap->flip(context->xBarg, context->yBarg);
2152 context->status = SUCCESS;
2153 } else {
2154 IMAGE_LOGE("Null native ref");
2155 context->status = ERR_IMAGE_INIT_ABNORMAL;
2156 }
2157 } else {
2158 IMAGE_LOGD("Flip has failed. do nothing");
2159 }
2160 }
2161
Flip(napi_env env,napi_callback_info info)2162 napi_value PixelMapNapi::Flip(napi_env env, napi_callback_info info)
2163 {
2164 NapiValues nVal;
2165 nVal.argc = NUM_3;
2166 napi_value argValue[NUM_3] = {0};
2167 nVal.argv = argValue;
2168 IMAGE_LOGD("Flip IN");
2169 if (!prepareNapiEnv(env, info, &nVal)) {
2170 return nVal.result;
2171 }
2172 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2173
2174 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
2175 IMAGE_LOGE("Invalid args count");
2176 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2177 } else {
2178 if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_0], &(nVal.context->xBarg))) {
2179 IMAGE_LOGE("Arg 0 type mismatch");
2180 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2181 }
2182 if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_1], &(nVal.context->yBarg))) {
2183 IMAGE_LOGE("Arg 1 type mismatch");
2184 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2185 }
2186 }
2187 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2188 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2189 }
2190
2191 if (nVal.context->callbackRef == nullptr) {
2192 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2193 }
2194 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2195 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Flip failed",
2196 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "FlipGeneralError",
2197 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2198 nVal.result);
2199 napi_value _resource = nullptr;
2200 napi_create_string_utf8(env, "Flip", NAPI_AUTO_LENGTH, &_resource);
2201 nVal.status = napi_create_async_work(env, nullptr, _resource,
2202 [](napi_env env, void *data)
2203 {
2204 auto context = static_cast<PixelMapAsyncContext*>(data);
2205 FlipExec(env, context);
2206 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2207
2208 if (nVal.status == napi_ok) {
2209 nVal.status = napi_queue_async_work(env, nVal.context->work);
2210 if (nVal.status == napi_ok) {
2211 nVal.context.release();
2212 }
2213 }
2214 return nVal.result;
2215 }
2216
CropExec(napi_env env,PixelMapAsyncContext * context)2217 static void CropExec(napi_env env, PixelMapAsyncContext* context)
2218 {
2219 if (context == nullptr) {
2220 IMAGE_LOGE("Null context");
2221 return;
2222 }
2223 if (context->status == SUCCESS) {
2224 if (context->rPixelMap != nullptr) {
2225 context->status = context->rPixelMap->crop(context->area.region);
2226 } else {
2227 IMAGE_LOGE("Null native ref");
2228 context->status = ERR_IMAGE_INIT_ABNORMAL;
2229 }
2230 } else {
2231 IMAGE_LOGD("Crop has failed. do nothing");
2232 }
2233 }
2234
Crop(napi_env env,napi_callback_info info)2235 napi_value PixelMapNapi::Crop(napi_env env, napi_callback_info info)
2236 {
2237 NapiValues nVal;
2238 nVal.argc = NUM_2;
2239 napi_value argValue[NUM_2] = {0};
2240 nVal.argv = argValue;
2241 IMAGE_LOGD("Crop IN");
2242 if (!prepareNapiEnv(env, info, &nVal)) {
2243 return nVal.result;
2244 }
2245 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2246
2247 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
2248 IMAGE_LOGE("Invalid args count");
2249 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2250 } else {
2251 if (!parseRegion(env, nVal.argv[NUM_0], &(nVal.context->area.region))) {
2252 IMAGE_LOGE("Region type mismatch");
2253 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2254 }
2255 }
2256 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2257 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2258 }
2259
2260 if (nVal.context->callbackRef == nullptr) {
2261 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2262 }
2263 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2264 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Crop failed",
2265 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "CropGeneralError",
2266 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2267 nVal.result);
2268 napi_value _resource = nullptr;
2269 napi_create_string_utf8(env, "CropExec", NAPI_AUTO_LENGTH, &_resource);
2270 nVal.status = napi_create_async_work(env, nullptr, _resource,
2271 [](napi_env env, void *data)
2272 {
2273 auto context = static_cast<PixelMapAsyncContext*>(data);
2274 CropExec(env, context);
2275 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2276
2277 if (nVal.status == napi_ok) {
2278 nVal.status = napi_queue_async_work(env, nVal.context->work);
2279 if (nVal.status == napi_ok) {
2280 nVal.context.release();
2281 }
2282 }
2283 return nVal.result;
2284 }
2285
GetColorSpace(napi_env env,napi_callback_info info)2286 napi_value PixelMapNapi::GetColorSpace(napi_env env, napi_callback_info info)
2287 {
2288 NapiValues nVal;
2289 nVal.argc = NUM_0;
2290 IMAGE_LOGD("GetColorSpace IN");
2291 napi_get_undefined(env, &nVal.result);
2292 if (!prepareNapiEnv(env, info, &nVal)) {
2293 return ImageNapiUtils::ThrowExceptionError(
2294 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
2295 }
2296 if (nVal.argc != NUM_0) {
2297 return ImageNapiUtils::ThrowExceptionError(
2298 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
2299 }
2300 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
2301 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2302 "Pixelmap has crossed threads . GetColorSpace failed"),
2303 IMAGE_LOGE("Pixelmap has crossed threads . GetColorSpace failed"));
2304 #ifdef IMAGE_COLORSPACE_FLAG
2305 if (nVal.context->nConstructor->nativePixelMap_ == nullptr) {
2306 return ImageNapiUtils::ThrowExceptionError(
2307 env, ERR_IMAGE_DATA_ABNORMAL, "Invalid native pixelmap");
2308 }
2309 auto grCS = nVal.context->nConstructor->nativePixelMap_->InnerGetGrColorSpacePtr();
2310 if (grCS == nullptr) {
2311 return ImageNapiUtils::ThrowExceptionError(
2312 env, ERR_IMAGE_DATA_UNSUPPORT, "No colorspace in pixelmap");
2313 }
2314 auto resultValue = ColorManager::CreateJsColorSpaceObject(env, grCS);
2315 nVal.result = reinterpret_cast<napi_value>(resultValue);
2316 #else
2317 return ImageNapiUtils::ThrowExceptionError(
2318 env, ERR_INVALID_OPERATION, "Unsupported operation");
2319 #endif
2320 return nVal.result;
2321 }
2322
SetColorSpace(napi_env env,napi_callback_info info)2323 napi_value PixelMapNapi::SetColorSpace(napi_env env, napi_callback_info info)
2324 {
2325 NapiValues nVal;
2326 nVal.argc = NUM_1;
2327 napi_value argValue[NUM_1] = {0};
2328 nVal.argv = argValue;
2329 IMAGE_LOGD("SetColorSpace IN");
2330 napi_get_undefined(env, &nVal.result);
2331 if (!prepareNapiEnv(env, info, &nVal)) {
2332 return ImageNapiUtils::ThrowExceptionError(
2333 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
2334 }
2335 if (nVal.argc != NUM_1) {
2336 return ImageNapiUtils::ThrowExceptionError(
2337 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
2338 }
2339 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
2340 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2341 "Pixelmap has crossed threads . SetColorSpace failed"),
2342 IMAGE_LOGE("Pixelmap has crossed threads . SetColorSpace failed"));
2343 #ifdef IMAGE_COLORSPACE_FLAG
2344 nVal.context->colorSpace = ColorManager::GetColorSpaceByJSObject(env, nVal.argv[NUM_0]);
2345 if (nVal.context->colorSpace == nullptr) {
2346 return ImageNapiUtils::ThrowExceptionError(
2347 env, ERR_IMAGE_INVALID_PARAMETER, "ColorSpace mismatch");
2348 }
2349 nVal.context->nConstructor->nativePixelMap_->InnerSetColorSpace(*(nVal.context->colorSpace));
2350 #else
2351 return ImageNapiUtils::ThrowExceptionError(
2352 env, ERR_INVALID_OPERATION, "Unsupported operation");
2353 #endif
2354 return nVal.result;
2355 }
2356
Marshalling(napi_env env,napi_callback_info info)2357 napi_value PixelMapNapi::Marshalling(napi_env env, napi_callback_info info)
2358 {
2359 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
2360 NapiValues nVal;
2361 nVal.argc = NUM_1;
2362 napi_value argValue[NUM_1] = {0};
2363 nVal.argv = argValue;
2364 IMAGE_LOGD("Marshalling IN");
2365
2366 if (!prepareNapiEnv(env, info, &nVal)) {
2367 return ImageNapiUtils::ThrowExceptionError(
2368 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
2369 }
2370 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2371 if (nVal.argc != NUM_0 && nVal.argc != NUM_1) {
2372 return ImageNapiUtils::ThrowExceptionError(
2373 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
2374 }
2375 NAPI_MessageSequence *napiSequence = nullptr;
2376 napi_get_cb_info(env, info, &nVal.argc, nVal.argv, nullptr, nullptr);
2377 napi_unwrap(env, nVal.argv[0], reinterpret_cast<void**>(&napiSequence));
2378 auto messageParcel = napiSequence->GetMessageParcel();
2379 bool st = nVal.context->rPixelMap->Marshalling(*messageParcel);
2380 if (!st) {
2381 return ImageNapiUtils::ThrowExceptionError(
2382 env, ERR_IPC, "marshalling pixel map to parcel failed.");
2383 }
2384 return nVal.result;
2385 #else
2386 napi_value result = nullptr;
2387 return result;
2388 #endif
2389 }
2390
ApplyColorSpaceExec(napi_env env,PixelMapAsyncContext * context)2391 static void ApplyColorSpaceExec(napi_env env, PixelMapAsyncContext* context)
2392 {
2393 if (context == nullptr) {
2394 IMAGE_LOGE("Null context");
2395 return;
2396 }
2397 if (context->status != SUCCESS) {
2398 IMAGE_LOGD("ApplyColorSpace has failed. do nothing");
2399 return;
2400 }
2401 if (context->rPixelMap == nullptr || context->colorSpace == nullptr) {
2402 context->status = ERR_IMAGE_INIT_ABNORMAL;
2403 IMAGE_LOGE("ApplyColorSpace Null native ref");
2404 return;
2405 }
2406 context->status = context->rPixelMap->ApplyColorSpace(*(context->colorSpace));
2407 }
2408
ParseColorSpaceVal(napi_env env,napi_value val,PixelMapAsyncContext * context)2409 static void ParseColorSpaceVal(napi_env env, napi_value val, PixelMapAsyncContext* context)
2410 {
2411 if (context == nullptr) {
2412 IMAGE_LOGE("Null context");
2413 return;
2414 }
2415
2416 #ifdef IMAGE_COLORSPACE_FLAG
2417 context->colorSpace = ColorManager::GetColorSpaceByJSObject(env, val);
2418 if (context->colorSpace == nullptr) {
2419 context->status = ERR_IMAGE_INVALID_PARAMETER;
2420 }
2421 #else
2422 Val.context->status = ERR_IMAGE_DATA_UNSUPPORT;
2423 #endif
2424 }
2425
ApplyColorSpace(napi_env env,napi_callback_info info)2426 napi_value PixelMapNapi::ApplyColorSpace(napi_env env, napi_callback_info info)
2427 {
2428 NapiValues nVal;
2429 nVal.argc = NUM_2;
2430 napi_value argValue[NUM_2] = {0};
2431 nVal.argv = argValue;
2432 IMAGE_LOGD("ApplyColorSpace IN");
2433 if (!prepareNapiEnv(env, info, &nVal)) {
2434 return nVal.result;
2435 }
2436 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2437
2438 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
2439 IMAGE_LOGE("Invalid args count");
2440 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2441 } else {
2442 ParseColorSpaceVal(env, nVal.argv[NUM_0], nVal.context.get());
2443 }
2444 if (nVal.argc >= NUM_1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2445 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2446 }
2447
2448 if (nVal.context->callbackRef == nullptr) {
2449 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2450 }
2451 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2452 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . ApplyColorSpace failed",
2453 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "ApplyColorSpaceGeneralError",
2454 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2455 nVal.result);
2456 napi_value _resource = nullptr;
2457 napi_create_string_utf8(env, "ApplyColorSpace", NAPI_AUTO_LENGTH, &_resource);
2458 nVal.status = napi_create_async_work(env, nullptr, _resource, [](napi_env env, void *data) {
2459 auto context = static_cast<PixelMapAsyncContext*>(data);
2460 ApplyColorSpaceExec(env, context);
2461 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2462
2463 if (nVal.status == napi_ok) {
2464 nVal.status = napi_queue_async_work(env, nVal.context->work);
2465 if (nVal.status == napi_ok) {
2466 nVal.context.release();
2467 }
2468 }
2469 return nVal.result;
2470 }
2471
release()2472 void PixelMapNapi::release()
2473 {
2474 if (!isRelease) {
2475 if (nativePixelMap_ != nullptr) {
2476 nativePixelMap_.reset();
2477 }
2478 isRelease = true;
2479 }
2480 }
2481 } // namespace Media
2482 } // namespace OHOS
2483