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