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