1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "pixel_map_napi.h"
17 #include "media_errors.h"
18 #include "image_log.h"
19 #include "image_napi_utils.h"
20 #include "image_pixel_map_napi.h"
21 #include "image_source_napi.h"
22 #include "image_trace.h"
23 #include "log_tags.h"
24 #include "color_space_object_convertor.h"
25 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
26 #include <cstdint>
27 #include <regex>
28 #include <vector>
29 #include <memory>
30 #include "vpe_utils.h"
31 #include "napi_message_sequence.h"
32 #include "pixel_map_from_surface.h"
33 #include "transaction/rs_interfaces.h"
34 #include "color_utils.h"
35 #endif
36 #include "hitrace_meter.h"
37 #include "pixel_map.h"
38 #include "image_format_convert.h"
39 #include <securec.h>
40
41 #undef LOG_DOMAIN
42 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
43
44 #undef LOG_TAG
45 #define LOG_TAG "PixelMapNapi"
46
47 namespace {
48 constexpr uint32_t NUM_0 = 0;
49 constexpr uint32_t NUM_1 = 1;
50 constexpr uint32_t NUM_2 = 2;
51 constexpr uint32_t NUM_3 = 3;
52 constexpr uint32_t NUM_4 = 4;
53 }
54
55 enum class FormatType:int8_t {
56 UNKNOWN,
57 YUV,
58 RGB
59 };
60
61 namespace OHOS {
62 namespace Media {
63 static const std::string CREATE_PIXEL_MAP_FROM_PARCEL = "createPixelMapFromParcel";
64 static const std::string MARSHALLING = "marshalling";
65 static const std::map<std::string, std::set<uint32_t>> ETS_API_ERROR_CODE = {
66 {CREATE_PIXEL_MAP_FROM_PARCEL, {62980096, 62980105, 62980115, 62980097,
67 62980177, 62980178, 62980179, 62980180, 62980246}},
68 {MARSHALLING, {62980115, 62980097, 62980096}}
69 };
70 static const std::string CLASS_NAME = "PixelMap";
71 static const std::int32_t NEW_INSTANCE_ARGC = 1;
72 thread_local napi_ref PixelMapNapi::sConstructor_ = nullptr;
73 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
74 NAPI_MessageSequence* napi_messageSequence = nullptr;
75 #endif
76 napi_ref PixelMapNapi::AntiAliasingLevel_ = nullptr;
77 napi_ref PixelMapNapi::HdrMetadataKey_ = nullptr;
78 napi_ref PixelMapNapi::HdrMetadataType_ = nullptr;
79 static std::mutex pixelMapCrossThreadMutex_;
80 struct PositionArea {
81 void* pixels;
82 size_t size;
83 uint32_t offset;
84 uint32_t stride;
85 Rect region;
86 };
87
88 struct ImageEnum {
89 std::string name;
90 int32_t numVal;
91 std::string strVal;
92 };
93
94 static std::vector<struct ImageEnum> AntiAliasingLevelMap = {
95 {"NONE", 0, ""},
96 {"LOW", 1, ""},
97 {"MEDIUM", 2, ""},
98 {"HIGH", 3, ""},
99 };
100
101 static std::vector<struct ImageEnum> HdrMetadataKeyMap = {
102 {"HDR_METADATA_TYPE", 0, ""},
103 {"HDR_STATIC_METADATA", 1, ""},
104 {"HDR_DYNAMIC_METADATA", 2, ""},
105 {"HDR_GAINMAP_METADATA", 3, ""},
106 };
107
108 static std::vector<struct ImageEnum> HdrMetadataTypeMap = {
109 {"NONE", 0, ""},
110 {"BASE", 1, ""},
111 {"GAINMAP", 2, ""},
112 {"ALTERNATE", 3, ""},
113 };
114
115 struct PixelMapAsyncContext {
116 napi_env env;
117 napi_async_work work;
118 napi_deferred deferred;
119 napi_ref callbackRef;
120 napi_ref error = nullptr;
121 uint32_t status;
122 PixelMapNapi *nConstructor;
123 void* colorsBuffer;
124 size_t colorsBufferSize;
125 InitializationOptions opts;
126 PositionArea area;
127 std::shared_ptr<PixelMap> rPixelMap;
128 std::shared_ptr<PixelMap> alphaMap;
129 std::shared_ptr<PixelMap> wPixelMap;
130 double alpha = -1;
131 uint32_t resultUint32;
132 ImageInfo imageInfo;
133 double xArg = 0;
134 double yArg = 0;
135 bool xBarg = false;
136 bool yBarg = false;
137 std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace;
138 std::string surfaceId;
139 PixelFormat destFormat = PixelFormat::UNKNOWN;
140 FormatType srcFormatType = FormatType::UNKNOWN;
141 FormatType dstFormatType = FormatType::UNKNOWN;
142 AntiAliasingOption antiAliasing;
143 };
144 using PixelMapAsyncContextPtr = std::unique_ptr<PixelMapAsyncContext>;
145 std::shared_ptr<PixelMap> srcPixelMap = nullptr;
146
147 class AgainstTransferGC {
148 public:
149 std::shared_ptr<PixelMap> pixelMap = nullptr;
~AgainstTransferGC()150 ~AgainstTransferGC()
151 {
152 pixelMap = nullptr;
153 }
154 };
155
ParsePixlForamt(int32_t val)156 static PixelFormat ParsePixlForamt(int32_t val)
157 {
158 if (val < static_cast<int32_t>(PixelFormat::EXTERNAL_MAX)) {
159 return PixelFormat(val);
160 }
161
162 return PixelFormat::UNKNOWN;
163 }
164
ParseAlphaType(int32_t val)165 static AlphaType ParseAlphaType(int32_t val)
166 {
167 if (val <= static_cast<int32_t>(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
168 return AlphaType(val);
169 }
170
171 return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
172 }
173
ParseScaleMode(int32_t val)174 static ScaleMode ParseScaleMode(int32_t val)
175 {
176 if (val <= static_cast<int32_t>(ScaleMode::CENTER_CROP)) {
177 return ScaleMode(val);
178 }
179
180 return ScaleMode::FIT_TARGET_SIZE;
181 }
182
ParseAntiAliasingOption(int32_t val)183 static AntiAliasingOption ParseAntiAliasingOption(int32_t val)
184 {
185 if (val <= static_cast<int32_t>(AntiAliasingOption::SPLINE)) {
186 return AntiAliasingOption(val);
187 }
188
189 return AntiAliasingOption::NONE;
190 }
191
parseSize(napi_env env,napi_value root,Size * size)192 static bool parseSize(napi_env env, napi_value root, Size* size)
193 {
194 if (size == nullptr) {
195 return false;
196 }
197
198 if (!GET_INT32_BY_NAME(root, "height", size->height)) {
199 return false;
200 }
201
202 if (!GET_INT32_BY_NAME(root, "width", size->width)) {
203 return false;
204 }
205
206 return true;
207 }
208
parseInitializationOptions(napi_env env,napi_value root,InitializationOptions * opts)209 static bool parseInitializationOptions(napi_env env, napi_value root, InitializationOptions* opts)
210 {
211 uint32_t tmpNumber = 0;
212 napi_value tmpValue = nullptr;
213
214 if (opts == nullptr) {
215 return false;
216 }
217
218 if (!GET_BOOL_BY_NAME(root, "editable", opts->editable)) {
219 opts->editable = true;
220 }
221
222 if (!GET_UINT32_BY_NAME(root, "alphaType", tmpNumber)) {
223 IMAGE_LOGD("no alphaType in initialization options");
224 }
225 opts->alphaType = ParseAlphaType(tmpNumber);
226
227 tmpNumber = 0;
228 if (!GET_UINT32_BY_NAME(root, "pixelFormat", tmpNumber)) {
229 IMAGE_LOGD("no pixelFormat in initialization options");
230 }
231 opts->pixelFormat = ParsePixlForamt(tmpNumber);
232
233 tmpNumber = 0;
234 if (!GET_UINT32_BY_NAME(root, "srcPixelFormat", tmpNumber)) {
235 IMAGE_LOGD("no srcPixelFormat in initialization options");
236 }
237 opts->srcPixelFormat = ParsePixlForamt(tmpNumber);
238
239 tmpNumber = 0;
240 if (!GET_UINT32_BY_NAME(root, "scaleMode", tmpNumber)) {
241 IMAGE_LOGD("no scaleMode in initialization options");
242 }
243 opts->scaleMode = ParseScaleMode(tmpNumber);
244
245 if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
246 return false;
247 }
248
249 if (!parseSize(env, tmpValue, &(opts->size))) {
250 return false;
251 }
252 return true;
253 }
254
ParserImageType(napi_env env,napi_value argv)255 ImageType PixelMapNapi::ParserImageType(napi_env env, napi_value argv)
256 {
257 napi_value constructor = nullptr;
258 napi_value global = nullptr;
259 bool isInstance = false;
260 napi_status ret = napi_invalid_arg;
261
262 napi_get_global(env, &global);
263
264 ret = napi_get_named_property(env, global, "PixelMap", &constructor);
265 if (ret != napi_ok) {
266 IMAGE_LOGI("Get PixelMapNapi property failed!");
267 }
268
269 ret = napi_instanceof(env, argv, constructor, &isInstance);
270 if (ret == napi_ok && isInstance) {
271 return ImageType::TYPE_PIXEL_MAP;
272 }
273
274 IMAGE_LOGI("InValued type!");
275 return ImageType::TYPE_UNKNOWN;
276 }
277
parseRegion(napi_env env,napi_value root,Rect * region)278 static bool parseRegion(napi_env env, napi_value root, Rect* region)
279 {
280 napi_value tmpValue = nullptr;
281
282 if (region == nullptr) {
283 return false;
284 }
285
286 if (!GET_INT32_BY_NAME(root, "x", region->left)) {
287 return false;
288 }
289
290 if (!GET_INT32_BY_NAME(root, "y", region->top)) {
291 return false;
292 }
293
294 if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
295 return false;
296 }
297
298 if (!GET_INT32_BY_NAME(tmpValue, "height", region->height)) {
299 return false;
300 }
301
302 if (!GET_INT32_BY_NAME(tmpValue, "width", region->width)) {
303 return false;
304 }
305
306 return true;
307 }
308
parsePositionArea(napi_env env,napi_value root,PositionArea * area)309 static bool parsePositionArea(napi_env env, napi_value root, PositionArea* area)
310 {
311 napi_value tmpValue = nullptr;
312
313 if (area == nullptr) {
314 return false;
315 }
316
317 if (!GET_BUFFER_BY_NAME(root, "pixels", area->pixels, area->size)) {
318 return false;
319 }
320
321 if (!GET_UINT32_BY_NAME(root, "offset", area->offset)) {
322 return false;
323 }
324
325 if (!GET_UINT32_BY_NAME(root, "stride", area->stride)) {
326 return false;
327 }
328
329 if (!GET_NODE_BY_NAME(root, "region", tmpValue)) {
330 return false;
331 }
332
333 if (!parseRegion(env, tmpValue, &(area->region))) {
334 return false;
335 }
336 return true;
337 }
338
CreateEnumTypeObject(napi_env env,napi_valuetype type,napi_ref * ref,std::vector<struct ImageEnum> imageEnumMap)339 static napi_value CreateEnumTypeObject(napi_env env,
340 napi_valuetype type, napi_ref* ref, std::vector<struct ImageEnum> imageEnumMap)
341 {
342 napi_value result = nullptr;
343 napi_status status;
344 int32_t refCount = 1;
345 std::string propName;
346 status = napi_create_object(env, &result);
347 if (status == napi_ok) {
348 for (auto imgEnum : imageEnumMap) {
349 napi_value enumNapiValue = nullptr;
350 if (type == napi_string) {
351 status = napi_create_string_utf8(env, imgEnum.strVal.c_str(),
352 NAPI_AUTO_LENGTH, &enumNapiValue);
353 } else if (type == napi_number) {
354 status = napi_create_int32(env, imgEnum.numVal, &enumNapiValue);
355 } else {
356 IMAGE_LOGE("Unsupported type %{public}d!", type);
357 }
358 if (status == napi_ok && enumNapiValue != nullptr) {
359 status = napi_set_named_property(env, result, imgEnum.name.c_str(), enumNapiValue);
360 }
361 if (status != napi_ok) {
362 IMAGE_LOGE("Failed to add named prop!");
363 break;
364 }
365 }
366
367 if (status == napi_ok) {
368 status = napi_create_reference(env, result, refCount, ref);
369 if (status == napi_ok) {
370 return result;
371 }
372 }
373 }
374 IMAGE_LOGE("CreateEnumTypeObject is Failed!");
375 napi_get_undefined(env, &result);
376 return result;
377 }
378
CommonCallbackRoutine(napi_env env,PixelMapAsyncContext * & asyncContext,const napi_value & valueParam)379 static void CommonCallbackRoutine(napi_env env, PixelMapAsyncContext* &asyncContext, const napi_value &valueParam)
380 {
381 napi_value result[NUM_2] = {0};
382 napi_value retVal;
383 napi_value callback = nullptr;
384
385 napi_get_undefined(env, &result[NUM_0]);
386 napi_get_undefined(env, &result[NUM_1]);
387
388 napi_handle_scope scope = nullptr;
389 napi_open_handle_scope(env, &scope);
390 if (scope == nullptr) {
391 return;
392 }
393
394 if (asyncContext == nullptr) {
395 napi_close_handle_scope(env, scope);
396 return;
397 }
398 if (asyncContext->status == SUCCESS) {
399 result[NUM_1] = valueParam;
400 } else if (asyncContext->error != nullptr) {
401 napi_get_reference_value(env, asyncContext->error, &result[NUM_0]);
402 napi_delete_reference(env, asyncContext->error);
403 } else {
404 napi_create_uint32(env, asyncContext->status, &result[NUM_0]);
405 }
406
407 if (asyncContext->deferred) {
408 if (asyncContext->status == SUCCESS) {
409 napi_resolve_deferred(env, asyncContext->deferred, result[NUM_1]);
410 } else {
411 napi_reject_deferred(env, asyncContext->deferred, result[NUM_0]);
412 }
413 } else {
414 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
415 napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
416 napi_delete_reference(env, asyncContext->callbackRef);
417 }
418
419 napi_delete_async_work(env, asyncContext->work);
420 napi_close_handle_scope(env, scope);
421
422 delete asyncContext;
423 asyncContext = nullptr;
424 }
425
STATIC_COMPLETE_FUNC(EmptyResult)426 STATIC_COMPLETE_FUNC(EmptyResult)
427 {
428 napi_value result = nullptr;
429 napi_get_undefined(env, &result);
430
431 auto context = static_cast<PixelMapAsyncContext*>(data);
432
433 CommonCallbackRoutine(env, context, result);
434 }
435
STATIC_COMPLETE_FUNC(GeneralError)436 STATIC_COMPLETE_FUNC(GeneralError)
437 {
438 if (data == nullptr) {
439 IMAGE_LOGE("GeneralErrorComplete invalid parameter: data is null");
440 return;
441 }
442
443 napi_value result = nullptr;
444 napi_get_undefined(env, &result);
445 auto context = static_cast<PixelMapAsyncContext*>(data);
446 context->status = ERR_RESOURCE_UNAVAILABLE;
447 CommonCallbackRoutine(env, context, result);
448 }
449
PixelMapNapi()450 PixelMapNapi::PixelMapNapi():env_(nullptr)
451 {
452 static std::atomic<uint32_t> currentId = 0;
453 uniqueId_ = currentId.fetch_add(1, std::memory_order_relaxed);
454 }
455
~PixelMapNapi()456 PixelMapNapi::~PixelMapNapi()
457 {
458 release();
459 }
460
DoInitAfter(napi_env env,napi_value exports,napi_value constructor,size_t property_count,const napi_property_descriptor * properties)461 static napi_value DoInitAfter(napi_env env,
462 napi_value exports,
463 napi_value constructor,
464 size_t property_count,
465 const napi_property_descriptor* properties)
466 {
467 napi_value global = nullptr;
468 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
469 napi_get_global(env, &global)),
470 nullptr, IMAGE_LOGE("Init:get global fail")
471 );
472
473 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
474 napi_set_named_property(env, global, CLASS_NAME.c_str(), constructor)),
475 nullptr, IMAGE_LOGE("Init:set global named property fail")
476 );
477
478 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
479 napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor)),
480 nullptr, IMAGE_LOGE("set named property fail")
481 );
482
483 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
484 napi_define_properties(env, exports, property_count, properties)),
485 nullptr, IMAGE_LOGE("define properties fail")
486 );
487 return exports;
488 }
489
RegisterNapi()490 std::vector<napi_property_descriptor> PixelMapNapi::RegisterNapi()
491 {
492 std::vector<napi_property_descriptor> props = {
493 DECLARE_NAPI_FUNCTION("readPixelsToBuffer", ReadPixelsToBuffer),
494 DECLARE_NAPI_FUNCTION("readPixelsToBufferSync", ReadPixelsToBufferSync),
495 DECLARE_NAPI_FUNCTION("readPixels", ReadPixels),
496 DECLARE_NAPI_FUNCTION("readPixelsSync", ReadPixelsSync),
497 DECLARE_NAPI_FUNCTION("writePixels", WritePixels),
498 DECLARE_NAPI_FUNCTION("writePixelsSync", WritePixelsSync),
499 DECLARE_NAPI_FUNCTION("writeBufferToPixels", WriteBufferToPixels),
500 DECLARE_NAPI_FUNCTION("writeBufferToPixelsSync", WriteBufferToPixelsSync),
501 DECLARE_NAPI_FUNCTION("getImageInfo", GetImageInfo),
502 DECLARE_NAPI_FUNCTION("getImageInfoSync", GetImageInfoSync),
503 DECLARE_NAPI_FUNCTION("getBytesNumberPerRow", GetBytesNumberPerRow),
504 DECLARE_NAPI_FUNCTION("getPixelBytesNumber", GetPixelBytesNumber),
505 DECLARE_NAPI_FUNCTION("isSupportAlpha", IsSupportAlpha),
506 DECLARE_NAPI_FUNCTION("setAlphaAble", SetAlphaAble),
507 DECLARE_NAPI_FUNCTION("createAlphaPixelmap", CreateAlphaPixelmap),
508 DECLARE_NAPI_FUNCTION("createAlphaPixelmapSync", CreateAlphaPixelmapSync),
509 DECLARE_NAPI_FUNCTION("getDensity", GetDensity),
510 DECLARE_NAPI_FUNCTION("setDensity", SetDensity),
511 DECLARE_NAPI_FUNCTION("opacity", SetAlpha),
512 DECLARE_NAPI_FUNCTION("opacitySync", SetAlphaSync),
513 DECLARE_NAPI_FUNCTION("release", Release),
514 DECLARE_NAPI_FUNCTION("scale", Scale),
515 DECLARE_NAPI_FUNCTION("scaleSync", ScaleSync),
516 DECLARE_NAPI_FUNCTION("translate", Translate),
517 DECLARE_NAPI_FUNCTION("translateSync", TranslateSync),
518 DECLARE_NAPI_FUNCTION("rotate", Rotate),
519 DECLARE_NAPI_FUNCTION("rotateSync", RotateSync),
520 DECLARE_NAPI_FUNCTION("flip", Flip),
521 DECLARE_NAPI_FUNCTION("flipSync", FlipSync),
522 DECLARE_NAPI_FUNCTION("crop", Crop),
523 DECLARE_NAPI_FUNCTION("cropSync", CropSync),
524 DECLARE_NAPI_FUNCTION("getColorSpace", GetColorSpace),
525 DECLARE_NAPI_FUNCTION("setColorSpace", SetColorSpace),
526 DECLARE_NAPI_FUNCTION("applyColorSpace", ApplyColorSpace),
527 DECLARE_NAPI_FUNCTION("marshalling", Marshalling),
528 DECLARE_NAPI_FUNCTION("unmarshalling", Unmarshalling),
529 DECLARE_NAPI_GETTER("isEditable", GetIsEditable),
530 DECLARE_NAPI_GETTER("isStrideAlignment", GetIsStrideAlignment),
531 DECLARE_NAPI_FUNCTION("toSdr", ToSdr),
532 DECLARE_NAPI_FUNCTION("convertPixelFormat", ConvertPixelMapFormat),
533 DECLARE_NAPI_FUNCTION("setTransferDetached", SetTransferDetached),
534 DECLARE_NAPI_FUNCTION("getMetadata", GetMetadata),
535 DECLARE_NAPI_FUNCTION("setMetadata", SetMetadata),
536 DECLARE_NAPI_FUNCTION("setMetadataSync", SetMetadataSync),
537 DECLARE_NAPI_FUNCTION("setMemoryNameSync", SetMemoryNameSync),
538 };
539 return props;
540 }
541
Init(napi_env env,napi_value exports)542 napi_value PixelMapNapi::Init(napi_env env, napi_value exports)
543 {
544 std::vector<napi_property_descriptor> props = PixelMapNapi::RegisterNapi();
545 napi_property_descriptor static_prop[] = {
546 DECLARE_NAPI_STATIC_FUNCTION("createPixelMap", CreatePixelMap),
547 DECLARE_NAPI_STATIC_FUNCTION("createPremultipliedPixelMap", CreatePremultipliedPixelMap),
548 DECLARE_NAPI_STATIC_FUNCTION("createUnpremultipliedPixelMap", CreateUnpremultipliedPixelMap),
549 DECLARE_NAPI_STATIC_FUNCTION("createPixelMapSync", CreatePixelMapSync),
550 DECLARE_NAPI_STATIC_FUNCTION("unmarshalling", Unmarshalling),
551 DECLARE_NAPI_STATIC_FUNCTION(CREATE_PIXEL_MAP_FROM_PARCEL.c_str(), CreatePixelMapFromParcel),
552 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
553 DECLARE_NAPI_STATIC_FUNCTION("createPixelMapFromSurface", CreatePixelMapFromSurface),
554 DECLARE_NAPI_STATIC_FUNCTION("createPixelMapFromSurfaceSync", CreatePixelMapFromSurfaceSync),
555 DECLARE_NAPI_STATIC_FUNCTION("convertPixelFormat", ConvertPixelMapFormat),
556 #endif
557 DECLARE_NAPI_PROPERTY("AntiAliasingLevel",
558 CreateEnumTypeObject(env, napi_number, &AntiAliasingLevel_, AntiAliasingLevelMap)),
559 DECLARE_NAPI_PROPERTY("HdrMetadataKey",
560 CreateEnumTypeObject(env, napi_number, &HdrMetadataKey_, HdrMetadataKeyMap)),
561 DECLARE_NAPI_PROPERTY("HdrMetadataType",
562 CreateEnumTypeObject(env, napi_number, &HdrMetadataType_, HdrMetadataTypeMap)),
563 };
564
565 napi_value constructor = nullptr;
566
567 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
568 napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
569 Constructor, nullptr, props.size(),
570 props.data(), &constructor)),
571 nullptr, IMAGE_LOGE("define class fail")
572 );
573
574 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
575 napi_create_reference(env, constructor, 1, &sConstructor_)),
576 nullptr, IMAGE_LOGE("create reference fail")
577 );
578
579 auto result = DoInitAfter(env, exports, constructor,
580 IMG_ARRAY_SIZE(static_prop), static_prop);
581
582 IMAGE_LOGD("Init success");
583 return result;
584 }
585
GetPixelMap(napi_env env,napi_value pixelmap)586 std::shared_ptr<PixelMap> PixelMapNapi::GetPixelMap(napi_env env, napi_value pixelmap)
587 {
588 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
589
590 napi_status status = napi_unwrap(env, pixelmap, reinterpret_cast<void**>(&pixelMapNapi));
591 if (!IMG_IS_OK(status)) {
592 IMAGE_LOGE("GetPixelMap napi unwrap failed");
593 return nullptr;
594 }
595
596 if (pixelMapNapi == nullptr) {
597 IMAGE_LOGE("GetPixelMap pixmapNapi is nullptr");
598 return nullptr;
599 }
600
601 auto pixelmapNapiPtr = pixelMapNapi.release();
602 if (pixelmapNapiPtr == nullptr) {
603 IMAGE_LOGE("GetPixelMap pixelmapNapi is nullptr");
604 return nullptr;
605 }
606 return pixelmapNapiPtr->nativePixelMap_;
607 }
608
GetPixelMaps(napi_env env,napi_value pixelmaps)609 std::shared_ptr<std::vector<std::shared_ptr<PixelMap>>> PixelMapNapi::GetPixelMaps(napi_env env, napi_value pixelmaps)
610 {
611 auto PixelMaps = std::make_shared<std::vector<std::shared_ptr<PixelMap>>>();
612 uint32_t length = 0;
613 auto status = napi_get_array_length(env, pixelmaps, &length);
614 if (!IMG_IS_OK(status)) {
615 IMAGE_LOGE("GetPixelMaps napi get array length failed");
616 return nullptr;
617 }
618 for (uint32_t i = 0; i < length; ++i) {
619 napi_value element;
620 status = napi_get_element(env, pixelmaps, i, &element);
621 if (!IMG_IS_OK(status)) {
622 IMAGE_LOGE("GetPixelMaps napi get element failed");
623 return nullptr;
624 }
625 std::shared_ptr<PixelMap> pixelMap;
626 pixelMap = GetPixelMap(env, element);
627 PixelMaps->push_back(pixelMap);
628 }
629 return PixelMaps;
630 }
631
GetPixelMap()632 std::shared_ptr<PixelMap>* PixelMapNapi::GetPixelMap()
633 {
634 return &nativePixelMap_;
635 }
636
IsLockPixelMap()637 bool PixelMapNapi::IsLockPixelMap()
638 {
639 return (lockCount > 0);
640 }
641
LockPixelMap()642 bool PixelMapNapi::LockPixelMap()
643 {
644 lockCount++;
645 return true;
646 }
647
UnlockPixelMap()648 void PixelMapNapi::UnlockPixelMap()
649 {
650 if (lockCount > 0) {
651 lockCount--;
652 }
653 }
654
OHOS_MEDIA_GetPixelMap(napi_env env,napi_value value)655 extern "C" __attribute__((visibility("default"))) void* OHOS_MEDIA_GetPixelMap(napi_env env, napi_value value)
656 {
657 PixelMapNapi *pixmapNapi = nullptr;
658 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
659 if (pixmapNapi == nullptr) {
660 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
661 return nullptr;
662 }
663 return reinterpret_cast<void*>(pixmapNapi->GetPixelMap());
664 }
665
OHOS_MEDIA_GetImageInfo(napi_env env,napi_value value,OhosPixelMapInfo * info)666 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_GetImageInfo(napi_env env, napi_value value,
667 OhosPixelMapInfo *info)
668 {
669 IMAGE_LOGD("GetImageInfo IN");
670
671 if (info == nullptr) {
672 IMAGE_LOGE("info is nullptr");
673 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
674 }
675
676 PixelMapNapi *pixmapNapi = nullptr;
677 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
678 if (pixmapNapi == nullptr) {
679 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
680 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
681 }
682
683 std::shared_ptr<PixelMap> pixelMap = pixmapNapi->GetPixelNapiInner();
684 if ((pixelMap == nullptr)) {
685 IMAGE_LOGE("pixelMap is nullptr");
686 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
687 }
688
689 ImageInfo imageInfo;
690 pixelMap->GetImageInfo(imageInfo);
691 info->width = imageInfo.size.width;
692 info->height = imageInfo.size.height;
693 info->rowSize = pixelMap->GetRowStride();
694 info->pixelFormat = static_cast<int32_t>(imageInfo.pixelFormat);
695
696 IMAGE_LOGD("GetImageInfo, w=%{public}u, h=%{public}u, r=%{public}u, f=%{public}d",
697 info->width, info->height, info->rowSize, info->pixelFormat);
698
699 return OHOS_IMAGE_RESULT_SUCCESS;
700 }
701
OHOS_MEDIA_AccessPixels(napi_env env,napi_value value,uint8_t ** addrPtr)702 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_AccessPixels(napi_env env, napi_value value,
703 uint8_t** addrPtr)
704 {
705 IMAGE_LOGD("AccessPixels IN");
706
707 PixelMapNapi *pixmapNapi = nullptr;
708 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
709 if (pixmapNapi == nullptr) {
710 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
711 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
712 }
713
714 std::shared_ptr<PixelMap> pixelMap = pixmapNapi->GetPixelNapiInner();
715 if (pixelMap == nullptr) {
716 IMAGE_LOGE("pixelMap is nullptr");
717 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
718 }
719
720 const uint8_t *constPixels = pixelMap->GetPixels();
721 if (constPixels == nullptr) {
722 IMAGE_LOGE("const pixels is nullptr");
723 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
724 }
725
726 uint8_t *pixels = const_cast<uint8_t*>(constPixels);
727 if (pixels == nullptr) {
728 IMAGE_LOGE("pixels is nullptr");
729 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
730 }
731
732 pixmapNapi->LockPixelMap();
733
734 if (addrPtr != nullptr) {
735 *addrPtr = pixels;
736 }
737
738 IMAGE_LOGD("AccessPixels OUT");
739 return OHOS_IMAGE_RESULT_SUCCESS;
740 }
741
OHOS_MEDIA_UnAccessPixels(napi_env env,napi_value value)742 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_UnAccessPixels(napi_env env, napi_value value)
743 {
744 IMAGE_LOGD("UnAccessPixels IN");
745
746 PixelMapNapi *pixmapNapi = nullptr;
747 napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
748 if (pixmapNapi == nullptr) {
749 IMAGE_LOGE("pixmapNapi unwrapped is nullptr");
750 return OHOS_IMAGE_RESULT_BAD_PARAMETER;
751 }
752
753 pixmapNapi->UnlockPixelMap();
754
755 return OHOS_IMAGE_RESULT_SUCCESS;
756 }
757
DetachPixelMapFunc(napi_env env,void * value,void *)758 void *DetachPixelMapFunc(napi_env env, void *value, void *)
759 {
760 IMAGE_LOGD("DetachPixelMapFunc in");
761 if (value == nullptr) {
762 IMAGE_LOGE("DetachPixelMapFunc value is nullptr");
763 return value;
764 }
765 auto pixelNapi = reinterpret_cast<PixelMapNapi*>(value);
766 pixelNapi->setPixelNapiEditable(false);
767 AgainstTransferGC *data = new AgainstTransferGC();
768 data->pixelMap = pixelNapi->GetPixelNapiInner();
769 if (pixelNapi->GetTransferDetach()) {
770 pixelNapi->ReleasePixelNapiInner();
771 }
772 return reinterpret_cast<void*>(data);
773 }
774
NewPixelNapiInstance(napi_env & env,napi_value & constructor,std::shared_ptr<PixelMap> & pixelMap,napi_value & result)775 static napi_status NewPixelNapiInstance(napi_env &env, napi_value &constructor,
776 std::shared_ptr<PixelMap> &pixelMap, napi_value &result)
777 {
778 napi_status status;
779 if (pixelMap == nullptr) {
780 status = napi_invalid_arg;
781 IMAGE_LOGE("NewPixelNapiInstance pixelMap is nullptr");
782 return status;
783 }
784 size_t argc = NEW_INSTANCE_ARGC;
785 napi_value argv[NEW_INSTANCE_ARGC] = { 0 };
786 napi_create_int32(env, pixelMap->GetUniqueId(), &argv[0]);
787 PixelMapContainer::GetInstance().Insert(pixelMap->GetUniqueId(), pixelMap);
788 status = napi_new_instance(env, constructor, argc, argv, &result);
789 return status;
790 }
791
AttachPixelMapFunc(napi_env env,void * value,void *)792 napi_value AttachPixelMapFunc(napi_env env, void *value, void *)
793 {
794 if (value == nullptr) {
795 IMAGE_LOGE("attach value is nullptr");
796 return nullptr;
797 }
798 std::lock_guard<std::mutex> lock(pixelMapCrossThreadMutex_);
799
800 napi_value result = nullptr;
801 if (value == nullptr) {
802 IMAGE_LOGE("attach value lock losed");
803 napi_get_undefined(env, &result);
804 return result;
805 }
806 AgainstTransferGC *data = reinterpret_cast<AgainstTransferGC*>(value);
807 std::shared_ptr<PixelMap> attachPixelMap = std::move(data->pixelMap);
808 delete data;
809 if (attachPixelMap == nullptr) {
810 IMAGE_LOGE("AttachPixelMapFunc attachPixelMap is nullptr");
811 napi_get_undefined(env, &result);
812 return result;
813 }
814 napi_value constructor = nullptr;
815 napi_status status;
816
817 if (PixelMapNapi::GetConstructor() == nullptr) {
818 IMAGE_LOGI("PixelMapNapi::GetConstructor() is nullptr");
819 napi_value exports = nullptr;
820 napi_create_object(env, &exports);
821 PixelMapNapi::Init(env, exports);
822 }
823 napi_value globalValue;
824 napi_get_global(env, &globalValue);
825 status = napi_get_named_property(env, globalValue, CLASS_NAME.c_str(), &constructor);
826 if (!IMG_IS_OK(status)) {
827 IMAGE_LOGI("napi_get_named_property failed requireNapi in");
828 napi_value func;
829 napi_get_named_property(env, globalValue, "requireNapi", &func);
830
831 napi_value imageInfo;
832 napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
833 napi_value funcArgv[1] = { imageInfo };
834 napi_value returnValue;
835 napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
836 status = napi_get_named_property(env, globalValue, CLASS_NAME.c_str(), &constructor);
837 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("napi_get_named_property error"));
838 }
839
840 status = NewPixelNapiInstance(env, constructor, attachPixelMap, result);
841 if (!IMG_IS_OK(status)) {
842 IMAGE_LOGE("AttachPixelMapFunc napi_get_referencce_value failed");
843 }
844 return result;
845 }
846
Constructor(napi_env env,napi_callback_info info)847 napi_value PixelMapNapi::Constructor(napi_env env, napi_callback_info info)
848 {
849 napi_value undefineVar = nullptr;
850 napi_get_undefined(env, &undefineVar);
851
852 napi_status status;
853 napi_value thisVar = nullptr;
854 napi_get_undefined(env, &thisVar);
855 size_t argc = NEW_INSTANCE_ARGC;
856 napi_value argv[NEW_INSTANCE_ARGC] = { 0 };
857 IMAGE_LOGD("Constructor IN");
858 status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
859 IMG_NAPI_CHECK_RET(IMG_IS_READY(status, thisVar), undefineVar);
860 uint32_t pixelMapId = 0;
861 napi_get_value_uint32(env, argv[0], &pixelMapId);
862 std::unique_ptr<PixelMapNapi> pPixelMapNapi = std::make_unique<PixelMapNapi>();
863
864 IMG_NAPI_CHECK_RET(IMG_NOT_NULL(pPixelMapNapi), undefineVar);
865
866 pPixelMapNapi->env_ = env;
867 if (PixelMapContainer::GetInstance().Find(pixelMapId)) {
868 pPixelMapNapi->nativePixelMap_ = PixelMapContainer::GetInstance()[pixelMapId];
869 IMAGE_LOGD("Constructor in napi_id:%{public}d, id:%{public}d",
870 pPixelMapNapi->GetUniqueId(), pPixelMapNapi->nativePixelMap_->GetUniqueId());
871 } else {
872 IMAGE_LOGE("Constructor nativePixelMap is nullptr");
873 }
874
875 napi_coerce_to_native_binding_object(
876 env, thisVar, DetachPixelMapFunc, AttachPixelMapFunc, pPixelMapNapi.get(), nullptr);
877
878 status = napi_wrap_with_size(env, thisVar, reinterpret_cast<void*>(pPixelMapNapi.get()), PixelMapNapi::Destructor,
879 nullptr, nullptr, static_cast<size_t>(pPixelMapNapi->nativePixelMap_->GetByteCount()));
880 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), undefineVar, IMAGE_LOGE("Failure wrapping js to native napi"));
881
882 pPixelMapNapi.release();
883 PixelMapContainer::GetInstance().Erase(pixelMapId);
884 return thisVar;
885 }
886
Destructor(napi_env env,void * nativeObject,void * finalize)887 void PixelMapNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
888 {
889 if (nativeObject != nullptr) {
890 std::lock_guard<std::mutex> lock(pixelMapCrossThreadMutex_);
891 IMAGE_LOGD("Destructor pixelmapNapi");
892 delete reinterpret_cast<PixelMapNapi*>(nativeObject);
893 nativeObject = nullptr;
894 }
895 }
896
BuildContextError(napi_env env,napi_ref & error,const std::string errMsg,const int32_t errCode)897 static void BuildContextError(napi_env env, napi_ref &error, const std::string errMsg, const int32_t errCode)
898 {
899 IMAGE_LOGE("%{public}s", errMsg.c_str());
900 napi_value tmpError;
901 ImageNapiUtils::CreateErrorObj(env, tmpError, errCode, errMsg);
902 napi_create_reference(env, tmpError, NUM_1, &(error));
903 }
904
STATIC_EXEC_FUNC(CreatePixelMap)905 STATIC_EXEC_FUNC(CreatePixelMap)
906 {
907 if (data == nullptr) {
908 IMAGE_LOGE("CreatePixelMapExec invalid parameter: data is null");
909 return;
910 }
911
912 auto context = static_cast<PixelMapAsyncContext*>(data);
913 auto colors = static_cast<uint32_t*>(context->colorsBuffer);
914 if (colors == nullptr) {
915 if (context->opts.pixelFormat == PixelFormat::RGBA_1010102 ||
916 context->opts.pixelFormat == PixelFormat::YCBCR_P010 ||
917 context->opts.pixelFormat == PixelFormat::YCRCB_P010) {
918 context->opts.useDMA = true;
919 }
920 auto pixelmap = PixelMap::Create(context->opts);
921 context->rPixelMap = std::move(pixelmap);
922 } else {
923 if (context->opts.pixelFormat == PixelFormat::RGBA_1010102 ||
924 context->opts.pixelFormat == PixelFormat::YCBCR_P010 ||
925 context->opts.pixelFormat == PixelFormat::YCRCB_P010) {
926 context->rPixelMap = nullptr;
927 } else {
928 auto pixelmap = PixelMap::Create(colors, context->colorsBufferSize, context->opts);
929 context->rPixelMap = std::move(pixelmap);
930 }
931 }
932 if (IMG_NOT_NULL(context->rPixelMap)) {
933 context->status = SUCCESS;
934 } else {
935 context->status = ERROR;
936 }
937 }
938
CreatePixelMapComplete(napi_env env,napi_status status,void * data)939 void PixelMapNapi::CreatePixelMapComplete(napi_env env, napi_status status, void *data)
940 {
941 if (data == nullptr) {
942 IMAGE_LOGE("CreatePixelMapComplete invalid parameter: data is null");
943 return;
944 }
945
946 napi_value constructor = nullptr;
947 napi_value result = nullptr;
948
949 IMAGE_LOGD("CreatePixelMapComplete IN");
950 auto context = static_cast<PixelMapAsyncContext*>(data);
951
952 status = napi_get_reference_value(env, sConstructor_, &constructor);
953
954 if (IMG_IS_OK(status)) {
955 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
956 }
957
958 if (!IMG_IS_OK(status)) {
959 context->status = ERROR;
960 IMAGE_LOGE("New instance could not be obtained");
961 napi_get_undefined(env, &result);
962 }
963
964 CommonCallbackRoutine(env, context, result);
965 }
966
STATIC_EXEC_FUNC(CreatePremultipliedPixelMap)967 STATIC_EXEC_FUNC(CreatePremultipliedPixelMap)
968 {
969 if (data == nullptr) {
970 IMAGE_LOGE("CreatePremultipliedPixelMapExec invalid parameter: data is null");
971 return;
972 }
973
974 auto context = static_cast<PixelMapAsyncContext*>(data);
975 if (IMG_NOT_NULL(context->rPixelMap) && IMG_NOT_NULL(context->wPixelMap)) {
976 bool isPremul = true;
977 if (context->wPixelMap->IsEditable()) {
978 context->status = context->rPixelMap->ConvertAlphaFormat(*context->wPixelMap.get(), isPremul);
979 } else {
980 context->status = ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
981 }
982 } else {
983 context->status = ERR_IMAGE_READ_PIXELMAP_FAILED;
984 }
985 }
986
STATIC_EXEC_FUNC(CreateUnpremultipliedPixelMap)987 STATIC_EXEC_FUNC(CreateUnpremultipliedPixelMap)
988 {
989 if (data == nullptr) {
990 IMAGE_LOGE("CreateUnpremultipliedPixelMapExec invalid parameter: data is null");
991 return;
992 }
993
994 auto context = static_cast<PixelMapAsyncContext*>(data);
995 if (IMG_NOT_NULL(context->rPixelMap) && IMG_NOT_NULL(context->wPixelMap)) {
996 bool isPremul = false;
997 if (context->wPixelMap->IsEditable()) {
998 context->status = context->rPixelMap->ConvertAlphaFormat(*context->wPixelMap.get(), isPremul);
999 } else {
1000 context->status = ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
1001 }
1002 } else {
1003 context->status = ERR_IMAGE_READ_PIXELMAP_FAILED;
1004 }
1005 }
1006
CreatePremultipliedPixelMap(napi_env env,napi_callback_info info)1007 napi_value PixelMapNapi::CreatePremultipliedPixelMap(napi_env env, napi_callback_info info)
1008 {
1009 napi_value result = nullptr;
1010 napi_get_undefined(env, &result);
1011 int32_t refCount = 1;
1012 napi_status status;
1013 napi_value thisVar = nullptr;
1014 napi_value argValue[NUM_3] = {0};
1015 size_t argCount = NUM_3;
1016 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1017
1018 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1019 IMG_NAPI_CHECK_RET_D(argCount >= NUM_2,
1020 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1021 "Invalid args count"),
1022 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
1023 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1024
1025 if (ParserImageType(env, argValue[NUM_0]) == ImageType::TYPE_PIXEL_MAP &&
1026 ParserImageType(env, argValue[NUM_1]) == ImageType::TYPE_PIXEL_MAP) {
1027 asyncContext->rPixelMap = GetPixelMap(env, argValue[NUM_0]);
1028 asyncContext->wPixelMap = GetPixelMap(env, argValue[NUM_1]);
1029 if (asyncContext->rPixelMap == nullptr || asyncContext->wPixelMap == nullptr) {
1030 BuildContextError(env, asyncContext->error, "input image type mismatch", ERR_IMAGE_GET_DATA_ABNORMAL);
1031 }
1032 } else {
1033 BuildContextError(env, asyncContext->error, "input image type mismatch",
1034 ERR_IMAGE_GET_DATA_ABNORMAL);
1035 }
1036
1037 IMG_NAPI_CHECK_RET_D(asyncContext->error == nullptr, nullptr, IMAGE_LOGE("input image type mismatch"));
1038 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1039 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1040 }
1041 if (asyncContext->callbackRef == nullptr) {
1042 napi_create_promise(env, &(asyncContext->deferred), &result);
1043 }
1044
1045 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->error == nullptr,
1046 BuildContextError(env, asyncContext->error, "CreatePremultipliedPixelMapError", ERR_IMAGE_GET_DATA_ABNORMAL),
1047 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePremultipliedPixelMapGeneralError",
1048 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1049 result);
1050
1051 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePremultipliedPixelMap",
1052 CreatePremultipliedPixelMapExec, EmptyResultComplete, asyncContext, asyncContext->work);
1053
1054 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1055 nullptr, IMAGE_LOGE("fail to create async work"));
1056 return result;
1057 }
1058
CreateUnpremultipliedPixelMap(napi_env env,napi_callback_info info)1059 napi_value PixelMapNapi::CreateUnpremultipliedPixelMap(napi_env env, napi_callback_info info)
1060 {
1061 napi_value result = nullptr;
1062 napi_get_undefined(env, &result);
1063 int32_t refCount = 1;
1064 napi_status status;
1065 napi_value thisVar = nullptr;
1066 napi_value argValue[NUM_3] = {0};
1067 size_t argCount = NUM_3;
1068 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1069
1070 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1071 IMG_NAPI_CHECK_RET_D(argCount >= NUM_2,
1072 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1073 "Invalid args count"),
1074 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
1075 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1076
1077 if (ParserImageType(env, argValue[NUM_0]) == ImageType::TYPE_PIXEL_MAP &&
1078 ParserImageType(env, argValue[NUM_1]) == ImageType::TYPE_PIXEL_MAP) {
1079 asyncContext->rPixelMap = GetPixelMap(env, argValue[NUM_0]);
1080 asyncContext->wPixelMap = GetPixelMap(env, argValue[NUM_1]);
1081 if (asyncContext->rPixelMap == nullptr || asyncContext->wPixelMap == nullptr) {
1082 BuildContextError(env, asyncContext->error, "input image type mismatch", ERR_IMAGE_GET_DATA_ABNORMAL);
1083 }
1084 } else {
1085 BuildContextError(env, asyncContext->error, "input image type mismatch",
1086 ERR_IMAGE_GET_DATA_ABNORMAL);
1087 }
1088
1089 IMG_NAPI_CHECK_RET_D(asyncContext->error == nullptr, nullptr, IMAGE_LOGE("input image type mismatch"));
1090 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1091 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1092 }
1093 if (asyncContext->callbackRef == nullptr) {
1094 napi_create_promise(env, &(asyncContext->deferred), &result);
1095 }
1096
1097 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->error == nullptr,
1098 BuildContextError(env, asyncContext->error, "CreateUnpremultipliedPixelMapError", ERR_IMAGE_GET_DATA_ABNORMAL),
1099 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateUnpremultipliedPixelMapGeneralError",
1100 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1101 result);
1102
1103 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateUnpremultipliedPixelMap",
1104 CreateUnpremultipliedPixelMapExec, EmptyResultComplete, asyncContext, asyncContext->work);
1105
1106 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1107 nullptr, IMAGE_LOGE("fail to create async work"));
1108 return result;
1109 }
1110
CreatePixelMap(napi_env env,napi_callback_info info)1111 napi_value PixelMapNapi::CreatePixelMap(napi_env env, napi_callback_info info)
1112 {
1113 if (PixelMapNapi::GetConstructor() == nullptr) {
1114 napi_value exports = nullptr;
1115 napi_create_object(env, &exports);
1116 PixelMapNapi::Init(env, exports);
1117 }
1118
1119 napi_value result = nullptr;
1120 napi_get_undefined(env, &result);
1121
1122 int32_t refCount = 1;
1123
1124 napi_status status;
1125 napi_value thisVar = nullptr;
1126 napi_value argValue[NUM_4] = {0};
1127 size_t argCount = NUM_4;
1128 IMAGE_LOGD("CreatePixelMap IN");
1129
1130 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1131
1132 // we are static method!
1133 // thisVar is nullptr here
1134 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1135 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1136
1137 status = napi_get_arraybuffer_info(env, argValue[NUM_0], &(asyncContext->colorsBuffer),
1138 &(asyncContext->colorsBufferSize));
1139
1140 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
1141
1142 IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[1], &(asyncContext->opts)),
1143 nullptr, IMAGE_LOGE("InitializationOptions mismatch"));
1144
1145 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1146 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1147 }
1148
1149 if (asyncContext->callbackRef == nullptr) {
1150 napi_create_promise(env, &(asyncContext->deferred), &result);
1151 } else {
1152 napi_get_undefined(env, &result);
1153 }
1154
1155 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMap",
1156 CreatePixelMapExec, CreatePixelMapComplete, asyncContext, asyncContext->work);
1157
1158 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1159 nullptr, IMAGE_LOGE("fail to create async work"));
1160 return result;
1161 }
1162
CreatePixelMapSync(napi_env env,napi_callback_info info)1163 napi_value PixelMapNapi::CreatePixelMapSync(napi_env env, napi_callback_info info)
1164 {
1165 if (PixelMapNapi::GetConstructor() == nullptr) {
1166 napi_value exports = nullptr;
1167 napi_create_object(env, &exports);
1168 PixelMapNapi::Init(env, exports);
1169 }
1170
1171 napi_value result = nullptr;
1172 napi_get_undefined(env, &result);
1173 napi_value constructor = nullptr;
1174 napi_status status;
1175 napi_value thisVar = nullptr;
1176 napi_value argValue[NUM_2] = {0};
1177 size_t argCount = NUM_2;
1178 IMAGE_LOGD("CreatePixelMap IN");
1179
1180 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1181
1182 // we are static method!
1183 // thisVar is nullptr here
1184 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1185
1186 IMG_NAPI_CHECK_RET_D(argCount == NUM_2 || argCount == NUM_1,
1187 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1188 "Invalid args count"),
1189 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
1190 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1191
1192 if (argCount == NUM_2) {
1193 status = napi_get_arraybuffer_info(env, argValue[NUM_0], &(asyncContext->colorsBuffer),
1194 &(asyncContext->colorsBufferSize));
1195 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
1196 IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[1], &(asyncContext->opts)),
1197 nullptr, IMAGE_LOGE("InitializationOptions mismatch"));
1198 } else if (argCount == NUM_1) {
1199 IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[NUM_0], &(asyncContext->opts)),
1200 nullptr, IMAGE_LOGE("InitializationOptions mismatch"));
1201 }
1202 CreatePixelMapExec(env, static_cast<void*>((asyncContext).get()));
1203 status = napi_get_reference_value(env, sConstructor_, &constructor);
1204 if (IMG_IS_OK(status)) {
1205 status = NewPixelNapiInstance(env, constructor, asyncContext->rPixelMap, result);
1206 }
1207 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to create pixel map sync"));
1208 return result;
1209 }
1210
1211 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
STATIC_EXEC_FUNC(CreatePixelMapFromSurface)1212 STATIC_EXEC_FUNC(CreatePixelMapFromSurface)
1213 {
1214 if (data == nullptr) {
1215 IMAGE_LOGE("CreatePixelMapFromSurfaceExec invalid parameter: data is null");
1216 return;
1217 }
1218
1219 auto context = static_cast<PixelMapAsyncContext*>(data);
1220 IMAGE_LOGD("CreatePixelMapFromSurface id:%{public}s,area:%{public}d,%{public}d,%{public}d,%{public}d",
1221 context->surfaceId.c_str(), context->area.region.left, context->area.region.top,
1222 context->area.region.height, context->area.region.width);
1223
1224 if (!std::regex_match(context->surfaceId, std::regex("\\d+"))) {
1225 IMAGE_LOGE("CreatePixelMapFromSurface empty or invalid surfaceId");
1226 context->status = ERR_IMAGE_INVALID_PARAMETER;
1227 return;
1228 }
1229
1230 auto &rsClient = Rosen::RSInterfaces::GetInstance();
1231 OHOS::Rect r = {
1232 .x = context->area.region.left,
1233 .y = context->area.region.top,
1234 .w = context->area.region.width,
1235 .h = context->area.region.height,
1236 };
1237 std::shared_ptr<Media::PixelMap> pixelMap =
1238 rsClient.CreatePixelMapFromSurfaceId(std::stoull(context->surfaceId), r);
1239 #ifndef EXT_PIXEL
1240 if (pixelMap == nullptr) {
1241 pixelMap = CreatePixelMapFromSurfaceId(std::stoull(context->surfaceId), context->area.region);
1242 }
1243 #endif
1244 context->rPixelMap = std::move(pixelMap);
1245
1246 if (IMG_NOT_NULL(context->rPixelMap)) {
1247 context->status = SUCCESS;
1248 } else {
1249 context->status = ERR_IMAGE_INVALID_PARAMETER;
1250 }
1251 }
1252
CreatePixelMapFromSurfaceComplete(napi_env env,napi_status status,void * data)1253 void PixelMapNapi::CreatePixelMapFromSurfaceComplete(napi_env env, napi_status status, void *data)
1254 {
1255 if (data == nullptr) {
1256 IMAGE_LOGE("CreatePixelMapFromSurfaceComplete invalid parameter: data is null");
1257 return;
1258 }
1259
1260 napi_value constructor = nullptr;
1261 napi_value result = nullptr;
1262
1263 IMAGE_LOGD("CreatePixelMapFromSurface IN");
1264 auto context = static_cast<PixelMapAsyncContext*>(data);
1265 status = napi_get_reference_value(env, sConstructor_, &constructor);
1266 if (IMG_IS_OK(status)) {
1267 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
1268 }
1269
1270 if (!IMG_IS_OK(status)) {
1271 context->status = ERR_IMAGE_PIXELMAP_CREATE_FAILED;
1272 IMAGE_LOGE("New instance could not be obtained");
1273 napi_get_undefined(env, &result);
1274 }
1275
1276 CommonCallbackRoutine(env, context, result);
1277 }
1278
setSurfaceId(const char * surfaceId,std::string & dst)1279 void setSurfaceId(const char *surfaceId, std::string &dst)
1280 {
1281 dst = surfaceId;
1282 }
1283
GetStringArgument(napi_env env,napi_value value)1284 static std::string GetStringArgument(napi_env env, napi_value value)
1285 {
1286 std::string strValue = "";
1287 size_t bufLength = 0;
1288 napi_status status = napi_get_value_string_utf8(env, value, nullptr, NUM_0, &bufLength);
1289 if (status == napi_ok && bufLength > NUM_0 && bufLength < PATH_MAX) {
1290 char *buffer = reinterpret_cast<char *>(malloc((bufLength + NUM_1) * sizeof(char)));
1291 if (buffer == nullptr) {
1292 IMAGE_LOGE("No memory");
1293 return strValue;
1294 }
1295
1296 status = napi_get_value_string_utf8(env, value, buffer, bufLength + NUM_1, &bufLength);
1297 if (status == napi_ok) {
1298 IMAGE_LOGD("Get Success");
1299 strValue.assign(buffer, 0, bufLength + NUM_1);
1300 }
1301 if (buffer != nullptr) {
1302 free(buffer);
1303 buffer = nullptr;
1304 }
1305 }
1306 return strValue;
1307 }
1308 #endif
1309
CreatePixelMapFromSurface(napi_env env,napi_callback_info info)1310 napi_value PixelMapNapi::CreatePixelMapFromSurface(napi_env env, napi_callback_info info)
1311 {
1312 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
1313 napi_value result = nullptr;
1314 return result;
1315 #else
1316 napi_value globalValue;
1317 napi_get_global(env, &globalValue);
1318 napi_value func;
1319 napi_get_named_property(env, globalValue, "requireNapi", &func);
1320
1321 napi_value imageInfo;
1322 napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
1323 napi_value funcArgv[1] = { imageInfo };
1324 napi_value returnValue;
1325 napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
1326
1327 napi_value result = nullptr;
1328 napi_get_undefined(env, &result);
1329 int32_t refCount = 1;
1330 napi_status status;
1331 napi_value thisVar = nullptr;
1332 napi_value argValue[NUM_4] = {0};
1333 size_t argCount = NUM_4;
1334 IMAGE_LOGD("CreatePixelMapFromSurface IN");
1335 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1336 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1337 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1338 asyncContext->surfaceId = GetStringArgument(env, argValue[NUM_0]);
1339 bool ret = parseRegion(env, argValue[NUM_1], &(asyncContext->area.region));
1340 IMAGE_LOGD("CreatePixelMapFromSurface get data: %{public}d", ret);
1341 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1342 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1343 }
1344 if (asyncContext->callbackRef == nullptr) {
1345 napi_create_promise(env, &(asyncContext->deferred), &result);
1346 } else {
1347 napi_get_undefined(env, &result);
1348 }
1349 IMG_NAPI_CHECK_BUILD_ERROR(ret,
1350 BuildContextError(env, asyncContext->error, "image invalid parameter", ERR_IMAGE_GET_DATA_ABNORMAL),
1351 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMapFromSurfaceGeneralError",
1352 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1353 result);
1354 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMapFromSurface",
1355 CreatePixelMapFromSurfaceExec, CreatePixelMapFromSurfaceComplete, asyncContext, asyncContext->work);
1356 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1357 nullptr, IMAGE_LOGE("fail to create async work"));
1358 return result;
1359 #endif
1360 }
1361
CreatePixelMapFromSurfaceSync(napi_env env,napi_callback_info info)1362 napi_value PixelMapNapi::CreatePixelMapFromSurfaceSync(napi_env env, napi_callback_info info)
1363 {
1364 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
1365 napi_value result = nullptr;
1366 return result;
1367 #else
1368 if (PixelMapNapi::GetConstructor() == nullptr) {
1369 napi_value exports = nullptr;
1370 napi_create_object(env, &exports);
1371 PixelMapNapi::Init(env, exports);
1372 }
1373
1374 napi_value result = nullptr;
1375 napi_get_undefined(env, &result);
1376 napi_value constructor = nullptr;
1377 napi_status status;
1378 napi_value thisVar = nullptr;
1379 napi_value argValue[NUM_2] = {0};
1380 size_t argCount = NUM_2;
1381 IMAGE_LOGD("CreatePixelMap IN");
1382
1383 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1384 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1385 ImageNapiUtils::ThrowExceptionError(env, ERR_IMAGE_GET_DATA_ABNORMAL,
1386 "Failed to get data"),
1387 IMAGE_LOGE("CreatePixelMapFromSurfaceSync fail to get data"));
1388
1389 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1390 asyncContext->surfaceId = GetStringArgument(env, argValue[NUM_0]);
1391 bool ret = parseRegion(env, argValue[NUM_1], &(asyncContext->area.region));
1392 IMAGE_LOGD("CreatePixelMapFromSurface get data: %{public}d", ret);
1393 IMG_NAPI_CHECK_RET_D(ret,
1394 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1395 "Invalid args count"),
1396 IMAGE_LOGE("CreatePixelMapFromSurfaceSync invalid args count"));
1397
1398 CreatePixelMapFromSurfaceExec(env, static_cast<void*>((asyncContext).get()));
1399 status = napi_get_reference_value(env, sConstructor_, &constructor);
1400 if (IMG_IS_OK(status)) {
1401 status = NewPixelNapiInstance(env, constructor, asyncContext->rPixelMap, result);
1402 }
1403 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1404 ImageNapiUtils::ThrowExceptionError(env, ERR_IMAGE_PIXELMAP_CREATE_FAILED,
1405 "Failed to create pixelmap"),
1406 IMAGE_LOGE("CreatePixelMapFromSurfaceSync fail to create pixel map sync"));
1407 return result;
1408 #endif
1409 }
1410
CreatePixelMap(napi_env env,std::shared_ptr<PixelMap> pixelmap)1411 napi_value PixelMapNapi::CreatePixelMap(napi_env env, std::shared_ptr<PixelMap> pixelmap)
1412 {
1413 if (PixelMapNapi::GetConstructor() == nullptr) {
1414 napi_value exports = nullptr;
1415 napi_create_object(env, &exports);
1416 PixelMapNapi::Init(env, exports);
1417 }
1418
1419 napi_value constructor = nullptr;
1420 napi_value result = nullptr;
1421 napi_status status;
1422
1423 IMAGE_LOGD("CreatePixelMap IN");
1424 status = napi_get_reference_value(env, sConstructor_, &constructor);
1425
1426 if (IMG_IS_OK(status)) {
1427 status = NewPixelNapiInstance(env, constructor, pixelmap, result);
1428 }
1429
1430 if (!IMG_IS_OK(status)) {
1431 IMAGE_LOGE("CreatePixelMap | New instance could not be obtained");
1432 napi_get_undefined(env, &result);
1433 }
1434
1435 return result;
1436 }
1437
STATIC_EXEC_FUNC(Unmarshalling)1438 STATIC_EXEC_FUNC(Unmarshalling)
1439 {
1440 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1441 if (data == nullptr) {
1442 IMAGE_LOGE("UnmarshallingExec invalid parameter: data is null");
1443 return;
1444 }
1445 auto context = static_cast<PixelMapAsyncContext*>(data);
1446
1447 auto messageParcel = napi_messageSequence->GetMessageParcel();
1448 auto pixelmap = PixelMap::Unmarshalling(*messageParcel);
1449 std::unique_ptr<OHOS::Media::PixelMap> pixelmap_ptr(pixelmap);
1450
1451 context->rPixelMap = std::move(pixelmap_ptr);
1452
1453 if (IMG_NOT_NULL(context->rPixelMap)) {
1454 context->status = SUCCESS;
1455 } else {
1456 context->status = ERROR;
1457 }
1458 #endif
1459 }
1460
UnmarshallingComplete(napi_env env,napi_status status,void * data)1461 void PixelMapNapi::UnmarshallingComplete(napi_env env, napi_status status, void *data)
1462 {
1463 if (data == nullptr) {
1464 IMAGE_LOGE("UnmarshallingComplete invalid parameter: data is null");
1465 return;
1466 }
1467
1468 napi_value constructor = nullptr;
1469 napi_value result = nullptr;
1470
1471 IMAGE_LOGD("UnmarshallingComplete IN");
1472 auto context = static_cast<PixelMapAsyncContext*>(data);
1473
1474 status = napi_get_reference_value(env, sConstructor_, &constructor);
1475 if (IMG_IS_OK(status)) {
1476 status = NewPixelNapiInstance(env, constructor, context->rPixelMap, result);
1477 }
1478
1479 if (!IMG_IS_OK(status)) {
1480 context->status = ERROR;
1481 IMAGE_LOGE("New instance could not be obtained");
1482 napi_get_undefined(env, &result);
1483 }
1484
1485 CommonCallbackRoutine(env, context, result);
1486 }
1487
Unmarshalling(napi_env env,napi_callback_info info)1488 napi_value PixelMapNapi::Unmarshalling(napi_env env, napi_callback_info info)
1489 {
1490 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1491 if (PixelMapNapi::GetConstructor() == nullptr) {
1492 napi_value exports = nullptr;
1493 napi_create_object(env, &exports);
1494 PixelMapNapi::Init(env, exports);
1495 }
1496 napi_value result = nullptr;
1497 napi_get_undefined(env, &result);
1498
1499 int32_t refCount = 1;
1500
1501 napi_status status;
1502 napi_value thisVar = nullptr;
1503 napi_value argValue[NUM_4] = {0};
1504 size_t argCount = NUM_4;
1505 IMAGE_LOGD("Unmarshalling IN");
1506
1507 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1508
1509 // we are static method!
1510 // thisVar is nullptr here
1511 if (!IMG_IS_OK(status)) {
1512 return ImageNapiUtils::ThrowExceptionError(
1513 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to napi_get_cb_info");
1514 }
1515 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1516
1517 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1518 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1519 }
1520
1521 napi_unwrap(env, argValue[NUM_0], (void **)&napi_messageSequence);
1522
1523 if (asyncContext->callbackRef == nullptr) {
1524 napi_create_promise(env, &(asyncContext->deferred), &result);
1525 } else {
1526 napi_get_undefined(env, &result);
1527 }
1528
1529 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "Unmarshalling",
1530 UnmarshallingExec, UnmarshallingComplete, asyncContext, asyncContext->work);
1531
1532 if (!IMG_IS_OK(status)) {
1533 return ImageNapiUtils::ThrowExceptionError(
1534 env, ERROR, "Fail to create async work");
1535 }
1536 return result;
1537 #else
1538 napi_value result = nullptr;
1539 return result;
1540 #endif
1541 }
1542
ThrowExceptionError(napi_env env,const std::string & tag,const std::uint32_t & code,const std::string & info)1543 napi_value PixelMapNapi::ThrowExceptionError(napi_env env,
1544 const std::string &tag, const std::uint32_t &code, const std::string &info)
1545 {
1546 auto errNode = ETS_API_ERROR_CODE.find(tag);
1547 if (errNode != ETS_API_ERROR_CODE.end() &&
1548 errNode->second.find(code) != errNode->second.end()) {
1549 return ImageNapiUtils::ThrowExceptionError(env, code, info);
1550 }
1551 return ImageNapiUtils::ThrowExceptionError(env, ERROR, "Operation failed");
1552 }
1553
CreatePixelMapFromParcel(napi_env env,napi_callback_info info)1554 napi_value PixelMapNapi::CreatePixelMapFromParcel(napi_env env, napi_callback_info info)
1555 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
1556 {
1557 napi_value result = nullptr;
1558 return result;
1559 }
1560 #else
1561 {
1562 if (PixelMapNapi::GetConstructor() == nullptr) {
1563 napi_value exports = nullptr;
1564 napi_create_object(env, &exports);
1565 PixelMapNapi::Init(env, exports);
1566 }
1567 napi_value result = nullptr;
1568 napi_get_undefined(env, &result);
1569 napi_status status;
1570 napi_value thisVar = nullptr;
1571 napi_value argValue[NUM_1] = {0};
1572 size_t argCount = NUM_1;
1573 IMAGE_LOGD("CreatePixelMapFromParcel IN");
1574 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1575 if (!IMG_IS_OK(status) || argCount != NUM_1) {
1576 return PixelMapNapi::ThrowExceptionError(env,
1577 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IMAGE_INVALID_PARAMETER, "Fail to napi_get_cb_info");
1578 }
1579 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1580 napi_unwrap(env, argValue[NUM_0], (void **)&napi_messageSequence);
1581 auto messageParcel = napi_messageSequence->GetMessageParcel();
1582 if (messageParcel == nullptr) {
1583 return PixelMapNapi::ThrowExceptionError(env,
1584 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IPC, "get pacel failed");
1585 }
1586 PIXEL_MAP_ERR error;
1587 auto pixelmap = PixelMap::Unmarshalling(*messageParcel, error);
1588 if (!IMG_NOT_NULL(pixelmap)) {
1589 return PixelMapNapi::ThrowExceptionError(env,
1590 CREATE_PIXEL_MAP_FROM_PARCEL, error.errorCode, error.errorInfo);
1591 }
1592 std::shared_ptr<OHOS::Media::PixelMap> pixelPtr(pixelmap);
1593 napi_value constructor = nullptr;
1594 status = napi_get_reference_value(env, sConstructor_, &constructor);
1595 if (IMG_IS_OK(status)) {
1596 status = NewPixelNapiInstance(env, constructor, pixelPtr, result);
1597 }
1598 if (!IMG_IS_OK(status)) {
1599 IMAGE_LOGE("New instance could not be obtained");
1600 return PixelMapNapi::ThrowExceptionError(env,
1601 CREATE_PIXEL_MAP_FROM_PARCEL, ERR_IMAGE_NAPI_ERROR, "New instance could not be obtained");
1602 }
1603 return result;
1604 }
1605 #endif
1606
GetIsEditable(napi_env env,napi_callback_info info)1607 napi_value PixelMapNapi::GetIsEditable(napi_env env, napi_callback_info info)
1608 {
1609 napi_value result = nullptr;
1610 napi_get_undefined(env, &result);
1611
1612 napi_status status;
1613 napi_value thisVar = nullptr;
1614 size_t argCount = 0;
1615 IMAGE_LOGD("GetIsEditable IN");
1616
1617 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1618
1619 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1620
1621 PixelMapNapi* pixelMapNapi = nullptr;
1622 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1623
1624 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1625
1626 if (pixelMapNapi->nativePixelMap_ == nullptr) {
1627 return result;
1628 }
1629 bool isEditable = pixelMapNapi->nativePixelMap_->IsEditable();
1630
1631 napi_get_boolean(env, isEditable, &result);
1632
1633 return result;
1634 }
1635
GetIsStrideAlignment(napi_env env,napi_callback_info info)1636 napi_value PixelMapNapi::GetIsStrideAlignment(napi_env env, napi_callback_info info)
1637 {
1638 napi_value result = nullptr;
1639 napi_get_undefined(env, &result);
1640
1641 napi_status status;
1642 napi_value thisVar = nullptr;
1643 size_t argCount = 0;
1644 IMAGE_LOGD("GetIsStrideAlignment IN");
1645
1646 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1647
1648 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1649
1650 PixelMapNapi* pixelMapNapi = nullptr;
1651 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1652
1653 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi),
1654 result, IMAGE_LOGE("fail to unwrap context"));
1655
1656 if (pixelMapNapi->nativePixelMap_ == nullptr) {
1657 return result;
1658 }
1659 bool isDMA = pixelMapNapi->nativePixelMap_->IsStrideAlignment();
1660 napi_get_boolean(env, isDMA, &result);
1661 return result;
1662 }
1663
ReadPixelsToBuffer(napi_env env,napi_callback_info info)1664 napi_value PixelMapNapi::ReadPixelsToBuffer(napi_env env, napi_callback_info info)
1665 {
1666 ImageTrace imageTrace("PixelMapNapi::ReadPixelsToBuffer");
1667 napi_value result = nullptr;
1668 napi_get_undefined(env, &result);
1669
1670 int32_t refCount = 1;
1671 napi_status status;
1672 napi_value thisVar = nullptr;
1673 napi_value argValue[NUM_2] = {0};
1674 size_t argCount = NUM_2;
1675
1676 IMAGE_LOGD("ReadPixelsToBuffer IN");
1677 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1678
1679 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1680
1681 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1682 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1683
1684 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1685 nullptr, IMAGE_LOGE("fail to unwrap context"));
1686 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1687
1688 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1689 nullptr, IMAGE_LOGE("empty native pixelmap"));
1690
1691 status = napi_get_arraybuffer_info(env, argValue[NUM_0],
1692 &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
1693
1694 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("colors mismatch"));
1695
1696 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1697 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1698 }
1699
1700 if (asyncContext->callbackRef == nullptr) {
1701 napi_create_promise(env, &(asyncContext->deferred), &result);
1702 } else {
1703 napi_get_undefined(env, &result);
1704 }
1705
1706 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1707 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . ReadPixelsToBuffer failed",
1708 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsToBufferGeneralError",
1709 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1710 result);
1711 IMG_CREATE_CREATE_ASYNC_WORK_WITH_QOS(env, status, "ReadPixelsToBuffer",
1712 [](napi_env env, void *data) {
1713 auto context = static_cast<PixelMapAsyncContext*>(data);
1714 context->status = context->rPixelMap->ReadPixels(
1715 context->colorsBufferSize, static_cast<uint8_t*>(context->colorsBuffer));
1716 }, EmptyResultComplete, asyncContext, asyncContext->work, napi_qos_user_initiated);
1717
1718 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1719 nullptr, IMAGE_LOGE("fail to create async work"));
1720 return result;
1721 }
1722
ReadPixelsToBufferSync(napi_env env,napi_callback_info info)1723 napi_value PixelMapNapi::ReadPixelsToBufferSync(napi_env env, napi_callback_info info)
1724 {
1725 ImageTrace imageTrace("PixelMapNapi::ReadPixelsToBufferSync");
1726 napi_value result = nullptr;
1727 napi_get_undefined(env, &result);
1728 napi_status napiStatus;
1729 uint32_t status = SUCCESS;
1730 napi_value thisVar = nullptr;
1731 size_t argCount = NUM_1;
1732 napi_value argValue[NUM_1] = {0};
1733 void* colorsBuffer = nullptr;
1734 size_t colorsBufferSize = 0;
1735
1736 IMAGE_LOGD("ReadPixelsToBuffeSync IN");
1737 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
1738 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
1739 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
1740 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1741 "ReadPixelsToBuffeSync failed"),
1742 IMAGE_LOGE("ReadPixelsToBuffeSync failed, invalid parameter"));
1743
1744 napiStatus = napi_get_arraybuffer_info(env, argValue[NUM_0],
1745 &colorsBuffer, &colorsBufferSize);
1746 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
1747
1748 PixelMapNapi* pixelMapNapi = nullptr;
1749 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1750
1751 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1752 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1753 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1754 "Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"),
1755 IMAGE_LOGE("Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"));
1756
1757 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1758 status = pixelMapNapi->nativePixelMap_->ReadPixels(
1759 colorsBufferSize, static_cast<uint8_t*>(colorsBuffer));
1760 if (status != SUCCESS) {
1761 IMAGE_LOGE("ReadPixels failed");
1762 }
1763 } else {
1764 IMAGE_LOGE("Null native ref");
1765 }
1766 return result;
1767 }
1768
ReadPixels(napi_env env,napi_callback_info info)1769 napi_value PixelMapNapi::ReadPixels(napi_env env, napi_callback_info info)
1770 {
1771 napi_value result = nullptr;
1772 napi_get_undefined(env, &result);
1773
1774 int32_t refCount = 1;
1775 napi_status status;
1776 napi_value thisVar = nullptr;
1777 napi_value argValue[NUM_2] = {0};
1778 size_t argCount = NUM_2;
1779
1780 IMAGE_LOGD("ReadPixels IN");
1781 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1782
1783 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1784
1785 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1786 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1787
1788 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1789 nullptr, IMAGE_LOGE("fail to unwrap context"));
1790
1791 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1792
1793 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1794 nullptr, IMAGE_LOGE("empty native pixelmap"));
1795
1796 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
1797 nullptr, IMAGE_LOGE("fail to parse position area"));
1798
1799 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1800 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1801 }
1802
1803 if (asyncContext->callbackRef == nullptr) {
1804 napi_create_promise(env, &(asyncContext->deferred), &result);
1805 } else {
1806 napi_get_undefined(env, &result);
1807 }
1808
1809 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1810 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . ReadPixels failed",
1811 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsGeneralError",
1812 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1813 result);
1814 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixels",
1815 [](napi_env env, void *data) {
1816 auto context = static_cast<PixelMapAsyncContext*>(data);
1817 auto area = context->area;
1818 context->status = context->rPixelMap->ReadPixels(
1819 area.size, area.offset, area.stride, area.region, static_cast<uint8_t*>(area.pixels));
1820 }, EmptyResultComplete, asyncContext, asyncContext->work);
1821
1822 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1823 nullptr, IMAGE_LOGE("fail to create async work"));
1824 return result;
1825 }
1826
ReadPixelsSync(napi_env env,napi_callback_info info)1827 napi_value PixelMapNapi::ReadPixelsSync(napi_env env, napi_callback_info info)
1828 {
1829 napi_value result = nullptr;
1830 napi_get_undefined(env, &result);
1831
1832 napi_status status;
1833 napi_value thisVar = nullptr;
1834 napi_value argValue[NUM_1] = {0};
1835 size_t argCount = NUM_1;
1836 PositionArea area;
1837 IMAGE_LOGD("ReadPixelsSync IN");
1838 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1839
1840 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1841 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
1842 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1843 "Invalid args count"),
1844 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
1845 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &area),
1846 nullptr, IMAGE_LOGE("fail to parse position area"));
1847
1848 PixelMapNapi* pixelMapNapi = nullptr;
1849 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1850 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1851 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1852 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1853 "Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"),
1854 IMAGE_LOGE("Pixelmap has crossed threads . ReadPixelsToBuffeSync failed"));
1855
1856 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi->nativePixelMap_),
1857 nullptr, IMAGE_LOGE("empty native pixelmap"));
1858
1859 auto nativeStatus = pixelMapNapi->nativePixelMap_->ReadPixels(
1860 area.size, area.offset, area.stride, area.region, static_cast<uint8_t*>(area.pixels));
1861
1862 IMG_NAPI_CHECK_RET_D(nativeStatus == SUCCESS,
1863 nullptr, IMAGE_LOGE("fail to read pixels"));
1864 return result;
1865 }
1866
WritePixels(napi_env env,napi_callback_info info)1867 napi_value PixelMapNapi::WritePixels(napi_env env, napi_callback_info info)
1868 {
1869 napi_value result = nullptr;
1870 napi_get_undefined(env, &result);
1871
1872 int32_t refCount = 1;
1873 napi_status status;
1874 napi_value thisVar = nullptr;
1875 napi_value argValue[NUM_2] = {0};
1876 size_t argCount = NUM_2;
1877
1878 IMAGE_LOGD("WritePixels IN");
1879 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1880
1881 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1882
1883 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1884 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1885
1886 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1887 nullptr, IMAGE_LOGE("fail to unwrap context"));
1888 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1889
1890 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1891 nullptr, IMAGE_LOGE("empty native pixelmap"));
1892
1893 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
1894 nullptr, IMAGE_LOGE("fail to parse position area"));
1895
1896 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1897 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1898 }
1899
1900 if (asyncContext->callbackRef == nullptr) {
1901 napi_create_promise(env, &(asyncContext->deferred), &result);
1902 } else {
1903 napi_get_undefined(env, &result);
1904 }
1905 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
1906 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . WritePixels failed",
1907 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WritePixelsGeneralError",
1908 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
1909 result);
1910 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WritePixels",
1911 [](napi_env env, void *data) {
1912 auto context = static_cast<PixelMapAsyncContext*>(data);
1913 auto area = context->area;
1914 context->status = context->rPixelMap->WritePixels(
1915 static_cast<uint8_t*>(area.pixels), area.size, area.offset, area.stride, area.region);
1916 }, EmptyResultComplete, asyncContext, asyncContext->work);
1917
1918 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1919 nullptr, IMAGE_LOGE("fail to create async work"));
1920 return result;
1921 }
1922
WritePixelsSync(napi_env env,napi_callback_info info)1923 napi_value PixelMapNapi::WritePixelsSync(napi_env env, napi_callback_info info)
1924 {
1925 napi_value result = nullptr;
1926 napi_get_undefined(env, &result);
1927 napi_status napiStatus;
1928 uint32_t status = SUCCESS;
1929 napi_value thisVar = nullptr;
1930 size_t argCount = NUM_1;
1931 napi_value argValue[NUM_1] = {0};
1932 PositionArea area;
1933 IMAGE_LOGD("WritePixelsSyncIN");
1934 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
1935 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to arg info"));
1936 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
1937 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
1938 "Invalid args count"),
1939 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
1940 IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &area),
1941 nullptr, IMAGE_LOGE("fail to parse position area"));
1942
1943 PixelMapNapi* pixelMapNapi = nullptr;
1944 napiStatus = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1945 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
1946 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
1947 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
1948 "Pixelmap has crossed threads . WritePixelsSync failed"),
1949 IMAGE_LOGE("Pixelmap has crossed threads . WritePixelsSync failed"));
1950
1951 if (pixelMapNapi->nativePixelMap_ != nullptr) {
1952 status = pixelMapNapi->nativePixelMap_->WritePixels(
1953 static_cast<uint8_t*>(area.pixels), area.size, area.offset, area.stride, area.region);
1954 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr,
1955 IMAGE_LOGE("fail to write pixels"));
1956 } else {
1957 IMAGE_LOGE("Null native ref");
1958 }
1959 return result;
1960 }
1961
WriteBufferToPixels(napi_env env,napi_callback_info info)1962 napi_value PixelMapNapi::WriteBufferToPixels(napi_env env, napi_callback_info info)
1963 {
1964 ImageTrace imageTrace("PixelMapNapi::WriteBufferToPixels");
1965 napi_value result = nullptr;
1966 napi_get_undefined(env, &result);
1967
1968 int32_t refCount = 1;
1969 napi_status status;
1970 napi_value thisVar = nullptr;
1971 napi_value argValue[NUM_2] = {0};
1972 size_t argCount = NUM_2;
1973
1974 IMAGE_LOGD("WriteBufferToPixels IN");
1975 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1976
1977 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
1978
1979 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1980 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1981
1982 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1983 nullptr, IMAGE_LOGE("fail to unwrap context"));
1984 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1985
1986 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1987 nullptr, IMAGE_LOGE("empty native pixelmap"));
1988 status = napi_get_arraybuffer_info(env, argValue[NUM_0],
1989 &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
1990
1991 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1992 nullptr, IMAGE_LOGE("fail to get buffer info"));
1993
1994 if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1995 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1996 }
1997
1998 if (asyncContext->callbackRef == nullptr) {
1999 napi_create_promise(env, &(asyncContext->deferred), &result);
2000 } else {
2001 napi_get_undefined(env, &result);
2002 }
2003 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
2004 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . WriteBufferToPixels failed",
2005 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WriteBufferToPixelsGeneralError",
2006 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
2007 result);
2008 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WriteBufferToPixels",
2009 [](napi_env env, void *data) {
2010 auto context = static_cast<PixelMapAsyncContext*>(data);
2011 context->status = context->rPixelMap->WritePixels(static_cast<uint8_t*>(context->colorsBuffer),
2012 context->colorsBufferSize);
2013 }, EmptyResultComplete, asyncContext, asyncContext->work);
2014
2015 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
2016 nullptr, IMAGE_LOGE("fail to create async work"));
2017 return result;
2018 }
2019
WriteBufferToPixelsSync(napi_env env,napi_callback_info info)2020 napi_value PixelMapNapi::WriteBufferToPixelsSync(napi_env env, napi_callback_info info)
2021 {
2022 ImageTrace imageTrace("PixelMapNapi::WriteBufferToPixelsSync");
2023 napi_value result = nullptr;
2024 napi_get_undefined(env, &result);
2025 napi_status napiStatus;
2026 uint32_t status = SUCCESS;
2027 napi_value thisVar = nullptr;
2028 size_t argCount = NUM_1;
2029 napi_value argValue[NUM_1] = {0};
2030 void* colorsBuffer = nullptr;
2031 size_t colorsBufferSize = 0;
2032
2033 IMAGE_LOGD("WriteBufferToPixelsSync IN");
2034 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2035 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2036 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
2037 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2038 "WriteBufferToPixelsSync failed"),
2039 IMAGE_LOGE("WriteBufferToPixelsSync failed, invalid parameter"));
2040
2041 napiStatus = napi_get_arraybuffer_info(env, argValue[NUM_0],
2042 &colorsBuffer, &colorsBufferSize);
2043 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
2044
2045 PixelMapNapi* pixelMapNapi = nullptr;
2046 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2047
2048 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2049 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2050 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2051 "Pixelmap has crossed threads . WriteBufferToPixelsSync failed"),
2052 IMAGE_LOGE("Pixelmap has crossed threads . WriteBufferToPixelsSync failed"));
2053
2054 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2055 status = pixelMapNapi->nativePixelMap_->WritePixels(
2056 static_cast<uint8_t*>(colorsBuffer), colorsBufferSize);
2057 if (status != SUCCESS) {
2058 IMAGE_LOGE("WritePixels failed");
2059 }
2060 } else {
2061 IMAGE_LOGE("Null native ref");
2062 }
2063 return result;
2064 }
2065
STATIC_NAPI_VALUE_FUNC(GetImageInfo)2066 STATIC_NAPI_VALUE_FUNC(GetImageInfo)
2067 {
2068 if (data == nullptr) {
2069 IMAGE_LOGE("GetImageInfoNapiValue invalid parameter: data is null");
2070 return nullptr;
2071 }
2072
2073 IMAGE_LOGD("[PixelMap]GetImageInfoNapiValue IN");
2074 napi_value result = nullptr;
2075 napi_create_object(env, &result);
2076 auto imageInfo = static_cast<ImageInfo*>(data);
2077 auto rPixelMap = static_cast<PixelMap*>(ptr);
2078 napi_value size = nullptr;
2079 napi_create_object(env, &size);
2080 napi_value sizeWith = nullptr;
2081 napi_create_int32(env, imageInfo->size.width, &sizeWith);
2082 napi_set_named_property(env, size, "width", sizeWith);
2083 napi_value sizeHeight = nullptr;
2084 napi_create_int32(env, imageInfo->size.height, &sizeHeight);
2085 napi_set_named_property(env, size, "height", sizeHeight);
2086 napi_set_named_property(env, result, "size", size);
2087 napi_value pixelFormatValue = nullptr;
2088 napi_create_int32(env, static_cast<int32_t>(imageInfo->pixelFormat), &pixelFormatValue);
2089 napi_set_named_property(env, result, "pixelFormat", pixelFormatValue);
2090 napi_value colorSpaceValue = nullptr;
2091 napi_create_int32(env, static_cast<int32_t>(imageInfo->colorSpace), &colorSpaceValue);
2092 napi_set_named_property(env, result, "colorSpace", colorSpaceValue);
2093 napi_value alphaTypeValue = nullptr;
2094 napi_create_int32(env, static_cast<int32_t>(imageInfo->alphaType), &alphaTypeValue);
2095 napi_set_named_property(env, result, "alphaType", alphaTypeValue);
2096 napi_value densityValue = nullptr;
2097 napi_create_int32(env, static_cast<int32_t>(imageInfo->baseDensity), &densityValue);
2098 napi_set_named_property(env, result, "density", densityValue);
2099 napi_value strideValue = nullptr;
2100 napi_create_int32(env, static_cast<int32_t>(rPixelMap->GetRowStride()), &strideValue);
2101 napi_set_named_property(env, result, "stride", strideValue);
2102 napi_value encodedFormatValue = nullptr;
2103 napi_create_string_utf8(env, imageInfo->encodedFormat.c_str(),
2104 imageInfo->encodedFormat.length(), &encodedFormatValue);
2105 napi_set_named_property(env, result, "mimeType", encodedFormatValue);
2106 napi_value isHdrValue = nullptr;
2107 napi_get_boolean(env, rPixelMap->IsHdr(), &isHdrValue);
2108 napi_set_named_property(env, result, "isHdr", isHdrValue);
2109 return result;
2110 }
2111
STATIC_COMPLETE_FUNC(GetImageInfo)2112 STATIC_COMPLETE_FUNC(GetImageInfo)
2113 {
2114 IMAGE_LOGD("[PixelMap]GetImageInfoComplete IN");
2115 auto context = static_cast<PixelMapAsyncContext*>(data);
2116 napi_value result = GetImageInfoNapiValue(env, &(context->imageInfo), context->rPixelMap.get());
2117
2118 if (!IMG_IS_OK(status)) {
2119 context->status = ERROR;
2120 IMAGE_LOGE("napi_create_int32 failed!");
2121 napi_get_undefined(env, &result);
2122 } else {
2123 context->status = SUCCESS;
2124 }
2125 IMAGE_LOGD("[PixelMap]GetImageInfoComplete OUT");
2126 CommonCallbackRoutine(env, context, result);
2127 }
GetImageInfo(napi_env env,napi_callback_info info)2128 napi_value PixelMapNapi::GetImageInfo(napi_env env, napi_callback_info info)
2129 {
2130 napi_value result = nullptr;
2131 napi_get_undefined(env, &result);
2132 int32_t refCount = 1;
2133 napi_status status;
2134 napi_value thisVar = nullptr;
2135 napi_value argValue[NUM_1] = {0};
2136 size_t argCount = 1;
2137 IMAGE_LOGD("GetImageInfo IN");
2138 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2139 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
2140 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
2141 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
2142 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
2143 nullptr, IMAGE_LOGE("fail to unwrap context"));
2144 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
2145 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
2146 nullptr, IMAGE_LOGE("empty native pixelmap"));
2147 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
2148 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
2149 }
2150 if (asyncContext->callbackRef == nullptr) {
2151 napi_create_promise(env, &(asyncContext->deferred), &result);
2152 } else {
2153 napi_get_undefined(env, &result);
2154 }
2155 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
2156 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . GetImageInfo failed",
2157 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfoGeneralError",
2158 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
2159 result);
2160 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfo",
2161 [](napi_env env, void *data) {
2162 auto context = static_cast<PixelMapAsyncContext*>(data);
2163 context->rPixelMap->GetImageInfo(context->imageInfo);
2164 context->status = SUCCESS;
2165 }, GetImageInfoComplete, asyncContext, asyncContext->work);
2166 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
2167 nullptr, IMAGE_LOGE("fail to create async work"));
2168 return result;
2169 }
2170
GetImageInfoSync(napi_env env,napi_callback_info info)2171 napi_value PixelMapNapi::GetImageInfoSync(napi_env env, napi_callback_info info)
2172 {
2173 napi_value result = nullptr;
2174 napi_get_undefined(env, &result);
2175 napi_status napiStatus;
2176 napi_value thisVar = nullptr;
2177 size_t argCount = NUM_0;
2178
2179 IMAGE_LOGD("GetImageInfoSync IN");
2180 IMG_JS_ARGS(env, info, napiStatus, argCount, nullptr, thisVar);
2181 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to arg info"));
2182
2183 PixelMapNapi* pixelMapNapi = nullptr;
2184 napiStatus = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2185
2186 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2187 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2188 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2189 "Pixelmap has crossed threads . GetImageInfoSync failed"),
2190 IMAGE_LOGE("Pixelmap has crossed threads . GetImageInfoSync failed"));
2191
2192 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2193 ImageInfo imageinfo;
2194 pixelMapNapi->nativePixelMap_->GetImageInfo(imageinfo);
2195 result = GetImageInfoNapiValue(env, &imageinfo, pixelMapNapi->nativePixelMap_.get());
2196 } else {
2197 IMAGE_LOGE("native pixelmap is nullptr!");
2198 }
2199 return result;
2200 }
2201
GetBytesNumberPerRow(napi_env env,napi_callback_info info)2202 napi_value PixelMapNapi::GetBytesNumberPerRow(napi_env env, napi_callback_info info)
2203 {
2204 ImageTrace imageTrace("PixelMapNapi::GetBytesNumberPerRow");
2205 napi_value result = nullptr;
2206 napi_get_undefined(env, &result);
2207
2208 napi_status status;
2209 napi_value thisVar = nullptr;
2210 size_t argCount = 0;
2211
2212 IMAGE_LOGD("GetBytesNumberPerRow IN");
2213 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
2214
2215 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2216
2217 PixelMapNapi* pixelMapNapi = nullptr;
2218 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2219
2220 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2221 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2222 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2223 "Pixelmap has crossed threads . GetBytesNumberPerRow failed"),
2224 IMAGE_LOGE("Pixelmap has crossed threads . GetBytesNumberPerRow failed"));
2225
2226 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2227 uint32_t rowBytes = pixelMapNapi->nativePixelMap_->GetRowBytes();
2228 status = napi_create_int32(env, rowBytes, &result);
2229 if (!IMG_IS_OK(status)) {
2230 IMAGE_LOGE("napi_create_int32 failed!");
2231 }
2232 } else {
2233 IMAGE_LOGE("native pixelmap is nullptr!");
2234 }
2235 return result;
2236 }
2237
GetPixelBytesNumber(napi_env env,napi_callback_info info)2238 napi_value PixelMapNapi::GetPixelBytesNumber(napi_env env, napi_callback_info info)
2239 {
2240 ImageTrace imageTrace("PixelMapNapi::GetPixelBytesNumber");
2241 napi_value result = nullptr;
2242 napi_get_undefined(env, &result);
2243
2244 napi_status status;
2245 napi_value thisVar = nullptr;
2246 size_t argCount = 0;
2247
2248 IMAGE_LOGD("GetPixelBytesNumber IN");
2249 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
2250
2251 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2252
2253 PixelMapNapi* pixelMapNapi = nullptr;
2254 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2255
2256 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2257 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2258 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2259 "Pixelmap has crossed threads . GetPixelBytesNumber failed"),
2260 IMAGE_LOGE("Pixelmap has crossed threads . GetPixelBytesNumber failed"));
2261
2262 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2263 uint32_t byteCount = pixelMapNapi->nativePixelMap_->GetByteCount();
2264 status = napi_create_int32(env, byteCount, &result);
2265 if (!IMG_IS_OK(status)) {
2266 IMAGE_LOGE("napi_create_int32 failed!");
2267 }
2268 } else {
2269 IMAGE_LOGE("native pixelmap is nullptr!");
2270 }
2271 return result;
2272 }
2273
IsSupportAlpha(napi_env env,napi_callback_info info)2274 napi_value PixelMapNapi::IsSupportAlpha(napi_env env, napi_callback_info info)
2275 {
2276 napi_value result = nullptr;
2277 napi_get_undefined(env, &result);
2278
2279 napi_status status;
2280 napi_value thisVar = nullptr;
2281 size_t argCount = NUM_0;
2282
2283 IMAGE_LOGD("IsSupportAlpha IN");
2284 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
2285
2286 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2287
2288 PixelMapNapi* pixelMapNapi = nullptr;
2289 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2290
2291 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2292 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2293 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2294 "Pixelmap has crossed threads . IsSupportAlpha failed"),
2295 IMAGE_LOGE("Pixelmap has crossed threads . IsSupportAlpha failed"));
2296
2297 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2298 AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
2299 bool isSupportAlpha = !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
2300 status = napi_get_boolean(env, isSupportAlpha, &result);
2301 if (!IMG_IS_OK(status)) {
2302 IMAGE_LOGE("napi_create_bool failed!");
2303 }
2304 } else {
2305 IMAGE_LOGE("native pixelmap is nullptr!");
2306 }
2307 return result;
2308 }
2309
SetAlphaAble(napi_env env,napi_callback_info info)2310 napi_value PixelMapNapi::SetAlphaAble(napi_env env, napi_callback_info info)
2311 {
2312 napi_value result = nullptr;
2313 napi_get_undefined(env, &result);
2314
2315 napi_status status;
2316 napi_value thisVar = nullptr;
2317 napi_value argValue[NUM_1] = {0};
2318 size_t argCount = NUM_1;
2319 bool isAlphaAble = false;
2320
2321 IMAGE_LOGD("SetAlphaAble IN");
2322 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2323
2324 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2325 NAPI_ASSERT(env, argCount > NUM_0, "Invalid input");
2326 NAPI_ASSERT(env, ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_boolean, "Invalid input type");
2327 NAPI_ASSERT(env, napi_get_value_bool(env, argValue[NUM_0], &isAlphaAble) == napi_ok, "Parse input error");
2328
2329 PixelMapNapi* pixelMapNapi = nullptr;
2330 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2331
2332 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2333 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2334 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2335 "Pixelmap has crossed threads . SetAlphaAble failed"),
2336 IMAGE_LOGE("Pixelmap has crossed threads . SetAlphaAble failed"));
2337 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2338 AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
2339 if (isAlphaAble && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
2340 pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
2341 } else if ((!isAlphaAble) && !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
2342 pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
2343 }
2344 } else {
2345 IMAGE_LOGE("native pixelmap is nullptr!");
2346 }
2347 return result;
2348 }
2349
CreateAlphaPixelmapComplete(napi_env env,napi_status status,void * data)2350 static void CreateAlphaPixelmapComplete(napi_env env, napi_status status, void *data)
2351 {
2352 if (data == nullptr) {
2353 IMAGE_LOGE("CreateAlphaPixelmapComplete invalid parameter: data is null");
2354 return;
2355 }
2356
2357 napi_value result = nullptr;
2358 napi_get_undefined(env, &result);
2359 auto context = static_cast<PixelMapAsyncContext*>(data);
2360
2361 if (context->alphaMap != nullptr) {
2362 result = PixelMapNapi::CreatePixelMap(env, context->alphaMap);
2363 context->status = SUCCESS;
2364 } else {
2365 context->status = ERROR;
2366 }
2367 CommonCallbackRoutine(env, context, result);
2368 }
2369
CreateAlphaPixelmap(napi_env env,napi_callback_info info)2370 napi_value PixelMapNapi::CreateAlphaPixelmap(napi_env env, napi_callback_info info)
2371 {
2372 napi_value result = nullptr;
2373 napi_get_undefined(env, &result);
2374 int32_t refCount = 1;
2375 napi_status status;
2376 napi_value thisVar = nullptr;
2377 napi_value argValue[NUM_1] = {0};
2378 size_t argCount = 1;
2379 IMAGE_LOGD("CreateAlphaPixelmap IN");
2380 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2381 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
2382 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
2383 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
2384 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
2385 nullptr, IMAGE_LOGE("fail to unwrap context"));
2386 asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
2387 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
2388 nullptr, IMAGE_LOGE("empty native pixelmap"));
2389 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
2390 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
2391 }
2392 if (asyncContext->callbackRef == nullptr) {
2393 napi_create_promise(env, &(asyncContext->deferred), &result);
2394 } else {
2395 napi_get_undefined(env, &result);
2396 }
2397 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->nConstructor->GetPixelNapiEditable(),
2398 BuildContextError(env, asyncContext->error, "pixelmap has crossed threads . CreateAlphaPixelmap failed",
2399 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateAlphaPixelmapGeneralError",
2400 [](napi_env env, void *data) {}, GeneralErrorComplete, asyncContext, asyncContext->work),
2401 result);
2402 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateAlphaPixelmap",
2403 [](napi_env env, void *data) {
2404 auto context = static_cast<PixelMapAsyncContext*>(data);
2405 InitializationOptions opts;
2406 opts.pixelFormat = PixelFormat::ALPHA_8;
2407 auto tmpPixelMap = PixelMap::Create(*(context->rPixelMap), opts);
2408 context->alphaMap = std::move(tmpPixelMap);
2409 context->status = SUCCESS;
2410 }, CreateAlphaPixelmapComplete, asyncContext, asyncContext->work);
2411 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
2412 nullptr, IMAGE_LOGE("fail to create async work"));
2413 return result;
2414 }
2415
CreateAlphaPixelmapSync(napi_env env,napi_callback_info info)2416 napi_value PixelMapNapi::CreateAlphaPixelmapSync(napi_env env, napi_callback_info info)
2417 {
2418 napi_value result = nullptr;
2419 napi_get_undefined(env, &result);
2420 napi_status napiStatus;
2421 uint32_t status = SUCCESS;
2422 napi_value thisVar = nullptr;
2423 size_t argCount = NUM_0;
2424
2425 IMAGE_LOGD("CreateAlphaPixelmapSync IN");
2426 IMG_JS_ARGS(env, info, napiStatus, argCount, nullptr, thisVar);
2427 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2428 IMG_NAPI_CHECK_RET_D(argCount == NUM_0,
2429 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2430 "CreateAlphaPixelmapSync failed"),
2431 IMAGE_LOGE("CreateAlphaPixelmapSync failed, invalid parameter"));
2432
2433 PixelMapNapi* pixelMapNapi = nullptr;
2434 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2435
2436 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2437 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2438 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2439 "Pixelmap has crossed threads . CreateAlphaPixelmapSync failed"),
2440 IMAGE_LOGE("Pixelmap has crossed threads . CreateAlphaPixelmapSync failed"));
2441
2442 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2443 InitializationOptions opts;
2444 opts.pixelFormat = PixelFormat::ALPHA_8;
2445 auto tmpPixelMap = PixelMap::Create(*(pixelMapNapi->nativePixelMap_), opts);
2446 result = PixelMapNapi::CreatePixelMap(env, std::move(tmpPixelMap));
2447 } else {
2448 IMAGE_LOGE("Null native ref");
2449 }
2450 return result;
2451 }
2452
GetDensity(napi_env env,napi_callback_info info)2453 napi_value PixelMapNapi::GetDensity(napi_env env, napi_callback_info info)
2454 {
2455 napi_value result = nullptr;
2456 napi_get_undefined(env, &result);
2457
2458 napi_status status;
2459 napi_value thisVar = nullptr;
2460 size_t argCount = 0;
2461
2462 IMAGE_LOGD("GetDensity IN");
2463 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
2464
2465 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2466
2467 PixelMapNapi* pixelMapNapi = nullptr;
2468 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2469
2470 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2471 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2472 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2473 "Pixelmap has crossed threads . GetDensity failed"),
2474 IMAGE_LOGE("Pixelmap has crossed threads . GetDensity failed"));
2475
2476 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2477 uint32_t baseDensity = static_cast<uint32_t>(pixelMapNapi->nativePixelMap_->GetBaseDensity());
2478 status = napi_create_int32(env, baseDensity, &result);
2479 if (!IMG_IS_OK(status)) {
2480 IMAGE_LOGE("napi_create_int32 failed!");
2481 }
2482 } else {
2483 IMAGE_LOGE("native pixelmap is nullptr!");
2484 }
2485 return result;
2486 }
2487
SetDensity(napi_env env,napi_callback_info info)2488 napi_value PixelMapNapi::SetDensity(napi_env env, napi_callback_info info)
2489 {
2490 napi_value result = nullptr;
2491 napi_get_undefined(env, &result);
2492
2493 napi_status status;
2494 napi_value thisVar = nullptr;
2495 napi_value argValue[NUM_1] = {0};
2496 size_t argCount = NUM_1;
2497 uint32_t density = 0;
2498
2499 IMAGE_LOGD("SetDensity IN");
2500 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2501 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2502
2503 NAPI_ASSERT(env,
2504 (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number),
2505 "Density input mismatch");
2506 NAPI_ASSERT(env, napi_get_value_uint32(env, argValue[NUM_0], &density) == napi_ok, "Could not parse density");
2507
2508 PixelMapNapi* pixelMapNapi = nullptr;
2509 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2510
2511 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2512 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2513 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2514 "Pixelmap has crossed threads . SetDensity failed"),
2515 IMAGE_LOGE("Pixelmap has crossed threads . SetDensity failed"));
2516 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2517 ImageInfo imageinfo;
2518 pixelMapNapi->nativePixelMap_->GetImageInfo(imageinfo);
2519 imageinfo.baseDensity = static_cast<int32_t>(density);
2520 pixelMapNapi->nativePixelMap_->SetImageInfo(imageinfo, true);
2521 } else {
2522 IMAGE_LOGE("native pixelmap is nullptr!");
2523 }
2524 return result;
2525 }
2526
Release(napi_env env,napi_callback_info info)2527 napi_value PixelMapNapi::Release(napi_env env, napi_callback_info info)
2528 {
2529 napi_value result = nullptr;
2530 napi_get_undefined(env, &result);
2531
2532 int32_t refCount = 1;
2533 napi_status status;
2534 napi_value thisVar = nullptr;
2535 napi_value argValue[1] = {0};
2536 size_t argCount = 1;
2537
2538 IMAGE_LOGD("Release IN");
2539 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
2540
2541 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, IMAGE_LOGE("fail to napi_get_cb_info"));
2542
2543 std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
2544 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
2545
2546 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
2547 nullptr, IMAGE_LOGE("fail to unwrap context"));
2548
2549 if (argCount == 1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
2550 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
2551 }
2552
2553 if (asyncContext->callbackRef == nullptr) {
2554 napi_create_promise(env, &(asyncContext->deferred), &result);
2555 } else {
2556 napi_get_undefined(env, &result);
2557 }
2558 if (asyncContext->nConstructor->IsLockPixelMap()) {
2559 asyncContext->status = ERROR;
2560 } else {
2561 if (asyncContext->nConstructor->nativePixelMap_ != nullptr) {
2562 IMAGE_LOGD("Release in napi_id:%{public}d, id:%{public}d",
2563 asyncContext->nConstructor->GetUniqueId(),
2564 asyncContext->nConstructor->nativePixelMap_->GetUniqueId());
2565 asyncContext->nConstructor->nativePixelMap_.reset();
2566 }
2567 asyncContext->status = SUCCESS;
2568 }
2569 IMG_CREATE_CREATE_ASYNC_WORK_WITH_QOS(env, status, "Release",
2570 [](napi_env env, void *data) {
2571 }, EmptyResultComplete, asyncContext, asyncContext->work, napi_qos_user_initiated);
2572
2573 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
2574 nullptr, IMAGE_LOGE("fail to create async work"));
2575 return result;
2576 }
2577
2578 struct NapiValues {
2579 napi_status status;
2580 napi_value thisVar = nullptr;
2581 napi_value result = nullptr;
2582 napi_value* argv = nullptr;
2583 size_t argc;
2584 int32_t refCount = 1;
2585 std::unique_ptr<PixelMapAsyncContext> context;
2586 };
2587
prepareNapiEnv(napi_env env,napi_callback_info info,struct NapiValues * nVal)2588 static bool prepareNapiEnv(napi_env env, napi_callback_info info, struct NapiValues* nVal)
2589 {
2590 if (nVal == nullptr) {
2591 IMAGE_LOGE("prepareNapiEnv invalid parameter: nVal is null");
2592 return false;
2593 }
2594
2595 napi_get_undefined(env, &(nVal->result));
2596 nVal->status = napi_get_cb_info(env, info, &(nVal->argc), nVal->argv, &(nVal->thisVar), nullptr);
2597 if (nVal->status != napi_ok) {
2598 IMAGE_LOGE("fail to napi_get_cb_info");
2599 return false;
2600 }
2601 nVal->context = std::make_unique<PixelMapAsyncContext>();
2602 nVal->status = napi_unwrap(env, nVal->thisVar, reinterpret_cast<void**>(&(nVal->context->nConstructor)));
2603 if (nVal->status != napi_ok) {
2604 IMAGE_LOGE("fail to unwrap context");
2605 return false;
2606 }
2607 if (nVal->context->nConstructor == nullptr ||
2608 nVal->context->nConstructor->GetPixelNapiInner() == nullptr) {
2609 IMAGE_LOGE("prepareNapiEnv pixelmap is nullptr");
2610 return false;
2611 }
2612 nVal->context->status = SUCCESS;
2613 return true;
2614 }
2615
SetAlphaExec(napi_env env,PixelMapAsyncContext * context)2616 static void SetAlphaExec(napi_env env, PixelMapAsyncContext* context)
2617 {
2618 if (context == nullptr) {
2619 IMAGE_LOGE("Null context");
2620 return;
2621 }
2622 if (context->status == SUCCESS) {
2623 if (context->rPixelMap != nullptr) {
2624 context->status = context->rPixelMap->SetAlpha(
2625 static_cast<float>(context->alpha));
2626 } else {
2627 IMAGE_LOGE("Null native ref");
2628 context->status = ERR_IMAGE_INIT_ABNORMAL;
2629 }
2630 } else {
2631 IMAGE_LOGD("Scale has failed. do nothing");
2632 }
2633 }
2634
SetAlpha(napi_env env,napi_callback_info info)2635 napi_value PixelMapNapi::SetAlpha(napi_env env, napi_callback_info info)
2636 {
2637 NapiValues nVal;
2638 nVal.argc = NUM_2;
2639 napi_value argValue[NUM_2] = {0};
2640 nVal.argv = argValue;
2641
2642 IMAGE_LOGD("SetAlpha IN");
2643 if (!prepareNapiEnv(env, info, &nVal)) {
2644 return nVal.result;
2645 }
2646 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2647
2648 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
2649 IMAGE_LOGE("Invalid args count %{public}zu", nVal.argc);
2650 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2651 } else {
2652 if (napi_ok !=
2653 napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->alpha))) {
2654 IMAGE_LOGE("Arg 0 type mismatch");
2655 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2656 }
2657 }
2658 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2659 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2660 }
2661
2662 if (nVal.context->callbackRef == nullptr) {
2663 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2664 }
2665 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2666 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . SetAlpha failed",
2667 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "SetAlphaGeneralError",
2668 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2669 nVal.result);
2670 napi_value _resource = nullptr;
2671 napi_create_string_utf8(env, "SetAlpha", NAPI_AUTO_LENGTH, &_resource);
2672 nVal.status = napi_create_async_work(env, nullptr, _resource,
2673 [](napi_env env, void *data) {
2674 auto context = static_cast<PixelMapAsyncContext*>(data);
2675 SetAlphaExec(env, context);
2676 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2677
2678 if (nVal.status == napi_ok) {
2679 nVal.status = napi_queue_async_work(env, nVal.context->work);
2680 if (nVal.status == napi_ok) {
2681 nVal.context.release();
2682 }
2683 }
2684 return nVal.result;
2685 }
2686
SetAlphaSync(napi_env env,napi_callback_info info)2687 napi_value PixelMapNapi::SetAlphaSync(napi_env env, napi_callback_info info)
2688 {
2689 napi_value result = nullptr;
2690 napi_get_undefined(env, &result);
2691 napi_status napiStatus;
2692 uint32_t status = SUCCESS;
2693 napi_value thisVar = nullptr;
2694 size_t argCount = NUM_1;
2695 napi_value argValue[NUM_1] = {0};
2696 double alpha = 0;
2697
2698 IMAGE_LOGD("SetAlphaSync IN");
2699 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2700 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
2701 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
2702 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2703 "SetAlphaSync failed"),
2704 IMAGE_LOGE("SetAlphaSync failed, invalid parameter"));
2705 napiStatus= napi_get_value_double(env, argValue[NUM_0], &alpha);
2706
2707 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
2708
2709 PixelMapNapi* pixelMapNapi = nullptr;
2710 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2711
2712 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2713 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2714 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2715 "Pixelmap has crossed threads . SetAlphaSync failed"),
2716 IMAGE_LOGE("Pixelmap has crossed threads . SetAlphaSync failed"));
2717
2718 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2719 status = pixelMapNapi->nativePixelMap_->SetAlpha(
2720 static_cast<float>(alpha));
2721 if (status != SUCCESS) {
2722 IMAGE_LOGE("SetAlphaSync failed");
2723 }
2724 } else {
2725 IMAGE_LOGE("Null native ref");
2726 }
2727 return result;
2728 }
2729
ScaleExec(napi_env env,PixelMapAsyncContext * context)2730 static void ScaleExec(napi_env env, PixelMapAsyncContext* context)
2731 {
2732 if (context == nullptr) {
2733 IMAGE_LOGE("Null context");
2734 return;
2735 }
2736 if (context->status == SUCCESS) {
2737 if (context->rPixelMap != nullptr) {
2738 if (context->antiAliasing == AntiAliasingOption::NONE) {
2739 context->rPixelMap->scale(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
2740 } else {
2741 context->rPixelMap->scale(static_cast<float>(context->xArg), static_cast<float>(context->yArg),
2742 context->antiAliasing);
2743 }
2744 context->status = SUCCESS;
2745 } else {
2746 IMAGE_LOGE("Null native ref");
2747 context->status = ERR_IMAGE_INIT_ABNORMAL;
2748 }
2749 } else {
2750 IMAGE_LOGD("Scale has failed. do nothing");
2751 }
2752 }
2753
NapiParseCallbackOrAntiAliasing(napi_env & env,NapiValues & nVal,int argi)2754 static void NapiParseCallbackOrAntiAliasing(napi_env &env, NapiValues &nVal, int argi)
2755 {
2756 if (ImageNapiUtils::getType(env, nVal.argv[argi]) == napi_function) {
2757 napi_create_reference(env, nVal.argv[argi], nVal.refCount, &(nVal.context->callbackRef));
2758 } else {
2759 int32_t antiAliasing;
2760 if (!IMG_IS_OK(napi_get_value_int32(env, nVal.argv[argi], &antiAliasing))) {
2761 IMAGE_LOGE("Arg %{public}d type mismatch", argi);
2762 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2763 }
2764 nVal.context->antiAliasing = ParseAntiAliasingOption(antiAliasing);
2765 }
2766 }
2767
Scale(napi_env env,napi_callback_info info)2768 napi_value PixelMapNapi::Scale(napi_env env, napi_callback_info info)
2769 {
2770 NapiValues nVal;
2771 nVal.argc = NUM_3;
2772 napi_value argValue[NUM_3] = {0};
2773 nVal.argv = argValue;
2774 IMAGE_LOGD("Scale IN");
2775 if (!prepareNapiEnv(env, info, &nVal)) {
2776 return nVal.result;
2777 }
2778 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2779
2780 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
2781 IMAGE_LOGE("Invalid args count %{public}zu", nVal.argc);
2782 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2783 } else {
2784 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
2785 IMAGE_LOGE("Arg 0 type mismatch");
2786 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2787 }
2788 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
2789 IMAGE_LOGE("Arg 1 type mismatch");
2790 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2791 }
2792 }
2793 if (nVal.argc == NUM_3) {
2794 NapiParseCallbackOrAntiAliasing(env, nVal, NUM_2);
2795 }
2796
2797 if (nVal.context->callbackRef == nullptr) {
2798 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2799 }
2800 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2801 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Scale failed",
2802 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "ScaleGeneralError",
2803 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2804 nVal.result);
2805 napi_value _resource = nullptr;
2806 napi_create_string_utf8(env, "Scale", NAPI_AUTO_LENGTH, &_resource);
2807 nVal.status = napi_create_async_work(env, nullptr, _resource,
2808 [](napi_env env, void *data) {
2809 auto context = static_cast<PixelMapAsyncContext*>(data);
2810 ScaleExec(env, context);
2811 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2812
2813 if (nVal.status == napi_ok) {
2814 nVal.status = napi_queue_async_work_with_qos(env, nVal.context->work, napi_qos_user_initiated);
2815 if (nVal.status == napi_ok) {
2816 nVal.context.release();
2817 }
2818 }
2819 return nVal.result;
2820 }
2821
ScaleSync(napi_env env,napi_callback_info info)2822 napi_value PixelMapNapi::ScaleSync(napi_env env, napi_callback_info info)
2823 {
2824 napi_value result = nullptr;
2825 napi_get_undefined(env, &result);
2826 napi_status napiStatus;
2827 uint32_t status = SUCCESS;
2828 napi_value thisVar = nullptr;
2829 size_t argCount = NUM_3;
2830 napi_value argValue[NUM_3] = {0};
2831 double xArg = 0;
2832 double yArg = 0;
2833 int32_t antiAliasing = 0;
2834 IMAGE_LOGD("ScaleSync IN");
2835 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2836
2837 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to arg info"));
2838
2839 IMG_NAPI_CHECK_RET_D(argCount == NUM_2 || argCount == NUM_3,
2840 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2841 "Invalid args count"),
2842 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
2843 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napi_get_value_double(env, argValue[NUM_0], &xArg)),
2844 result, IMAGE_LOGE("Arg 0 type mismatch"));
2845 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napi_get_value_double(env, argValue[NUM_1], &yArg)),
2846 result, IMAGE_LOGE("Arg 1 type mismatch"));
2847 if (argCount == NUM_3) {
2848 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napi_get_value_int32(env, argValue[NUM_2], &antiAliasing)),
2849 result, IMAGE_LOGE("Arg 2 type mismatch"));
2850 }
2851 PixelMapNapi* pixelMapNapi = nullptr;
2852 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2853
2854 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2855 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
2856 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
2857 "Pixelmap has crossed threads . ScaleSync failed"),
2858 IMAGE_LOGE("Pixelmap has crossed threads . ScaleSync failed"));
2859
2860 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2861 if (antiAliasing == 0) {
2862 pixelMapNapi->nativePixelMap_->scale(static_cast<float>(xArg), static_cast<float>(yArg));
2863 } else {
2864 pixelMapNapi->nativePixelMap_->scale(static_cast<float>(xArg), static_cast<float>(yArg),
2865 ParseAntiAliasingOption(antiAliasing));
2866 }
2867 } else {
2868 IMAGE_LOGE("Null native ref");
2869 }
2870 return result;
2871 }
2872
SetMemoryNameSync(napi_env env,napi_callback_info info)2873 napi_value PixelMapNapi::SetMemoryNameSync(napi_env env, napi_callback_info info)
2874 {
2875 napi_value result = nullptr;
2876 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
2877 return result;
2878 #else
2879 napi_get_undefined(env, &result);
2880 napi_status napiStatus;
2881 napi_value thisVar = nullptr;
2882 size_t argCount = NUM_1;
2883 napi_value argValue[NUM_1] = {0};
2884 NapiValues nVal;
2885 nVal.argc = NUM_1;
2886 nVal.argv = argValue;
2887 IMAGE_LOGD("SetName IN");
2888 if (!prepareNapiEnv(env, info, &nVal)) {
2889 return nVal.result;
2890 }
2891 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2892 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
2893 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to arg info"));
2894 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
2895 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
2896 "Invalid args count"),
2897 IMAGE_LOGE("Invalid args count %{public}zu", argCount));
2898 std::string pixelMapName = GetStringArgument(env, argValue[0]);
2899
2900 PixelMapNapi* pixelMapNapi = nullptr;
2901 napiStatus = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
2902
2903 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
2904
2905 // corssed threads error
2906 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2907 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . setname failed",
2908 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "SetNameError",
2909 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2910 nVal.result);
2911
2912 if (pixelMapNapi->nativePixelMap_ != nullptr) {
2913 uint32_t ret = pixelMapNapi->nativePixelMap_->SetMemoryName(pixelMapName);
2914 if (ret == SUCCESS) {
2915 return result;
2916 } else if (ret == ERR_MEMORY_NOT_SUPPORT) {
2917 ImageNapiUtils::ThrowExceptionError(env, ERR_MEMORY_NOT_SUPPORT, "fail set name");
2918 } else if (ret == COMMON_ERR_INVALID_PARAMETER) {
2919 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER, "name size out of range");
2920 }
2921 } else {
2922 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE, "Invalid nativePixelMap");
2923 IMAGE_LOGE("Null native pixemap object");
2924 }
2925 return result;
2926 #endif
2927 }
2928
TranslateExec(napi_env env,PixelMapAsyncContext * context)2929 static void TranslateExec(napi_env env, PixelMapAsyncContext* context)
2930 {
2931 if (context == nullptr) {
2932 IMAGE_LOGE("Null context");
2933 return;
2934 }
2935 if (context->status == SUCCESS) {
2936 if (context->rPixelMap != nullptr) {
2937 context->rPixelMap->translate(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
2938 context->status = SUCCESS;
2939 } else {
2940 IMAGE_LOGE("Null native ref");
2941 context->status = ERR_IMAGE_INIT_ABNORMAL;
2942 }
2943 } else {
2944 IMAGE_LOGD("Translate has failed. do nothing");
2945 }
2946 }
2947
Translate(napi_env env,napi_callback_info info)2948 napi_value PixelMapNapi::Translate(napi_env env, napi_callback_info info)
2949 {
2950 NapiValues nVal;
2951 nVal.argc = NUM_3;
2952 napi_value argValue[NUM_3] = {0};
2953 nVal.argv = argValue;
2954 IMAGE_LOGD("Translate IN");
2955 if (!prepareNapiEnv(env, info, &nVal)) {
2956 return nVal.result;
2957 }
2958 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
2959
2960 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
2961 IMAGE_LOGE("Invalid args count");
2962 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2963 } else {
2964 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
2965 IMAGE_LOGE("Arg 0 type mismatch");
2966 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2967 }
2968 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
2969 IMAGE_LOGE("Arg 1 type mismatch");
2970 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
2971 }
2972 }
2973 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
2974 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
2975 }
2976
2977 if (nVal.context->callbackRef == nullptr) {
2978 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
2979 }
2980 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
2981 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Translate failed",
2982 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "TranslateGeneralError",
2983 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
2984 nVal.result);
2985 napi_value _resource = nullptr;
2986 napi_create_string_utf8(env, "Translate", NAPI_AUTO_LENGTH, &_resource);
2987 nVal.status = napi_create_async_work(env, nullptr, _resource,
2988 [](napi_env env, void *data) {
2989 auto context = static_cast<PixelMapAsyncContext*>(data);
2990 TranslateExec(env, context);
2991 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
2992
2993 if (nVal.status == napi_ok) {
2994 nVal.status = napi_queue_async_work(env, nVal.context->work);
2995 if (nVal.status == napi_ok) {
2996 nVal.context.release();
2997 }
2998 }
2999 return nVal.result;
3000 }
3001
TranslateSync(napi_env env,napi_callback_info info)3002 napi_value PixelMapNapi::TranslateSync(napi_env env, napi_callback_info info)
3003 {
3004 napi_value result = nullptr;
3005 napi_get_undefined(env, &result);
3006 napi_status napiStatus;
3007 uint32_t status = SUCCESS;
3008 napi_value thisVar = nullptr;
3009 size_t argCount = NUM_2;
3010 napi_value argValue[NUM_2] = {0};
3011 double x = 0;
3012 double y = 0;
3013
3014 IMAGE_LOGD("TranslateSync IN");
3015 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
3016 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
3017 IMG_NAPI_CHECK_RET_D(argCount == NUM_2,
3018 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
3019 "TranslateSync failed"),
3020 IMAGE_LOGE("TranslateSync failed, invalid parameter"));
3021
3022 if (napi_ok != napi_get_value_double(env, argValue[NUM_0], &x) ||
3023 napi_ok != napi_get_value_double(env, argValue[NUM_1], &y)) {
3024 IMAGE_LOGE("get arraybuffer info failed");
3025 return result;
3026 }
3027
3028 PixelMapNapi* pixelMapNapi = nullptr;
3029 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
3030
3031 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
3032 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
3033 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3034 "Pixelmap has crossed threads . TranslateSync failed"),
3035 IMAGE_LOGE("Pixelmap has crossed threads . TranslateSync failed"));
3036
3037 if (pixelMapNapi->nativePixelMap_ != nullptr) {
3038 pixelMapNapi->nativePixelMap_->translate(static_cast<float>(x), static_cast<float>(y));
3039 } else {
3040 IMAGE_LOGE("Null native ref");
3041 }
3042 return result;
3043 }
3044
RotateExec(napi_env env,PixelMapAsyncContext * context)3045 static void RotateExec(napi_env env, PixelMapAsyncContext* context)
3046 {
3047 if (context == nullptr) {
3048 IMAGE_LOGE("Null context");
3049 return;
3050 }
3051 if (context->status == SUCCESS) {
3052 if (context->rPixelMap != nullptr) {
3053 context->rPixelMap->rotate(context->xArg);
3054 context->status = SUCCESS;
3055 } else {
3056 IMAGE_LOGE("Null native ref");
3057 context->status = ERR_IMAGE_INIT_ABNORMAL;
3058 }
3059 } else {
3060 IMAGE_LOGD("Rotate has failed. do nothing");
3061 }
3062 }
3063
Rotate(napi_env env,napi_callback_info info)3064 napi_value PixelMapNapi::Rotate(napi_env env, napi_callback_info info)
3065 {
3066 NapiValues nVal;
3067 nVal.argc = NUM_2;
3068 napi_value argValue[NUM_2] = {0};
3069 nVal.argv = argValue;
3070 IMAGE_LOGD("Rotate IN");
3071 if (!prepareNapiEnv(env, info, &nVal)) {
3072 return nVal.result;
3073 }
3074 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3075
3076 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
3077 IMAGE_LOGE("Invalid args count");
3078 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3079 } else {
3080 if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
3081 IMAGE_LOGE("Arg 0 type mismatch");
3082 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3083 }
3084 }
3085 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
3086 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
3087 }
3088
3089 if (nVal.context->callbackRef == nullptr) {
3090 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
3091 }
3092 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
3093 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Rotate failed",
3094 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "RotateGeneralError",
3095 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
3096 nVal.result);
3097 napi_value _resource = nullptr;
3098 napi_create_string_utf8(env, "Rotate", NAPI_AUTO_LENGTH, &_resource);
3099 nVal.status = napi_create_async_work(env, nullptr, _resource,
3100 [](napi_env env, void *data) {
3101 auto context = static_cast<PixelMapAsyncContext*>(data);
3102 RotateExec(env, context);
3103 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
3104
3105 if (nVal.status == napi_ok) {
3106 nVal.status = napi_queue_async_work(env, nVal.context->work);
3107 if (nVal.status == napi_ok) {
3108 nVal.context.release();
3109 }
3110 }
3111 return nVal.result;
3112 }
3113
RotateSync(napi_env env,napi_callback_info info)3114 napi_value PixelMapNapi::RotateSync(napi_env env, napi_callback_info info)
3115 {
3116 napi_value result = nullptr;
3117 napi_get_undefined(env, &result);
3118 napi_status napiStatus;
3119 uint32_t status = SUCCESS;
3120 napi_value thisVar = nullptr;
3121 size_t argCount = NUM_1;
3122 napi_value argValue[NUM_1] = {0};
3123 double angle = 0;
3124
3125 IMAGE_LOGD("RotateSync IN");
3126 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
3127 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
3128 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
3129 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
3130 "RotateSync failed"),
3131 IMAGE_LOGE("RotateSync failed, invalid parameter"));
3132 napiStatus = napi_get_value_double(env, argValue[NUM_0], &angle);
3133 IMG_NAPI_CHECK_RET_D(napiStatus == napi_ok, result, IMAGE_LOGE("get arraybuffer info failed"));
3134
3135 PixelMapNapi* pixelMapNapi = nullptr;
3136 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
3137
3138 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
3139 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
3140 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3141 "Pixelmap has crossed threads . RotateSync failed"),
3142 IMAGE_LOGE("Pixelmap has crossed threads . RotateSync failed"));
3143
3144 if (pixelMapNapi->nativePixelMap_ != nullptr) {
3145 pixelMapNapi->nativePixelMap_->rotate(static_cast<float>(angle));
3146 } else {
3147 IMAGE_LOGE("Null native ref");
3148 }
3149 return result;
3150 }
FlipExec(napi_env env,PixelMapAsyncContext * context)3151 static void FlipExec(napi_env env, PixelMapAsyncContext* context)
3152 {
3153 if (context == nullptr) {
3154 IMAGE_LOGE("Null context");
3155 return;
3156 }
3157 if (context->status == SUCCESS) {
3158 if (context->rPixelMap != nullptr) {
3159 context->rPixelMap->flip(context->xBarg, context->yBarg);
3160 context->status = SUCCESS;
3161 } else {
3162 IMAGE_LOGE("Null native ref");
3163 context->status = ERR_IMAGE_INIT_ABNORMAL;
3164 }
3165 } else {
3166 IMAGE_LOGD("Flip has failed. do nothing");
3167 }
3168 }
3169
Flip(napi_env env,napi_callback_info info)3170 napi_value PixelMapNapi::Flip(napi_env env, napi_callback_info info)
3171 {
3172 NapiValues nVal;
3173 nVal.argc = NUM_3;
3174 napi_value argValue[NUM_3] = {0};
3175 nVal.argv = argValue;
3176 IMAGE_LOGD("Flip IN");
3177 if (!prepareNapiEnv(env, info, &nVal)) {
3178 return nVal.result;
3179 }
3180 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3181
3182 if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
3183 IMAGE_LOGE("Invalid args count");
3184 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3185 } else {
3186 if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_0], &(nVal.context->xBarg))) {
3187 IMAGE_LOGE("Arg 0 type mismatch");
3188 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3189 }
3190 if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_1], &(nVal.context->yBarg))) {
3191 IMAGE_LOGE("Arg 1 type mismatch");
3192 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3193 }
3194 }
3195 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
3196 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
3197 }
3198
3199 if (nVal.context->callbackRef == nullptr) {
3200 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
3201 }
3202 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
3203 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Flip failed",
3204 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "FlipGeneralError",
3205 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
3206 nVal.result);
3207 napi_value _resource = nullptr;
3208 napi_create_string_utf8(env, "Flip", NAPI_AUTO_LENGTH, &_resource);
3209 nVal.status = napi_create_async_work(env, nullptr, _resource,
3210 [](napi_env env, void *data) {
3211 auto context = static_cast<PixelMapAsyncContext*>(data);
3212 FlipExec(env, context);
3213 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
3214
3215 if (nVal.status == napi_ok) {
3216 nVal.status = napi_queue_async_work(env, nVal.context->work);
3217 if (nVal.status == napi_ok) {
3218 nVal.context.release();
3219 }
3220 }
3221 return nVal.result;
3222 }
3223
FlipSync(napi_env env,napi_callback_info info)3224 napi_value PixelMapNapi::FlipSync(napi_env env, napi_callback_info info)
3225 {
3226 napi_value result = nullptr;
3227 napi_get_undefined(env, &result);
3228 napi_status napiStatus;
3229 uint32_t status = SUCCESS;
3230 napi_value thisVar = nullptr;
3231 size_t argCount = NUM_2;
3232 napi_value argValue[NUM_2] = {0};
3233 bool xBarg = 0;
3234 bool yBarg = 0;
3235
3236 IMAGE_LOGD("FlipSync IN");
3237 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
3238 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
3239 IMG_NAPI_CHECK_RET_D(argCount == NUM_2,
3240 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
3241 "FlipSync failed"),
3242 IMAGE_LOGE("FlipSync failed, invalid parameter"));
3243
3244 if (napi_ok != napi_get_value_bool(env, argValue[NUM_0], &xBarg)) {
3245 IMAGE_LOGE("Arg 0 type mismatch");
3246 status = COMMON_ERR_INVALID_PARAMETER;
3247 }
3248 if (napi_ok != napi_get_value_bool(env, argValue[NUM_1], &yBarg)) {
3249 IMAGE_LOGE("Arg 1 type mismatch");
3250 status = COMMON_ERR_INVALID_PARAMETER;
3251 }
3252
3253 IMG_NAPI_CHECK_RET_D(status == SUCCESS, result, IMAGE_LOGE("FlipSync failed, invalid parameter"));
3254
3255 PixelMapNapi* pixelMapNapi = nullptr;
3256 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
3257
3258 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
3259 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
3260 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3261 "Pixelmap has crossed threads . FlipSync failed"),
3262 IMAGE_LOGE("Pixelmap has crossed threads . FlipSync failed"));
3263
3264 if (pixelMapNapi->nativePixelMap_ != nullptr) {
3265 pixelMapNapi->nativePixelMap_->flip(xBarg, yBarg);
3266 } else {
3267 IMAGE_LOGE("Null native ref");
3268 }
3269 return result;
3270 }
3271
CropExec(napi_env env,PixelMapAsyncContext * context)3272 static void CropExec(napi_env env, PixelMapAsyncContext* context)
3273 {
3274 if (context == nullptr) {
3275 IMAGE_LOGE("Null context");
3276 return;
3277 }
3278 if (context->status == SUCCESS) {
3279 if (context->rPixelMap != nullptr) {
3280 context->status = context->rPixelMap->crop(context->area.region);
3281 } else {
3282 IMAGE_LOGE("Null native ref");
3283 context->status = ERR_IMAGE_INIT_ABNORMAL;
3284 }
3285 } else {
3286 IMAGE_LOGD("Crop has failed. do nothing");
3287 }
3288 }
3289
Crop(napi_env env,napi_callback_info info)3290 napi_value PixelMapNapi::Crop(napi_env env, napi_callback_info info)
3291 {
3292 NapiValues nVal;
3293 nVal.argc = NUM_2;
3294 napi_value argValue[NUM_2] = {0};
3295 nVal.argv = argValue;
3296 IMAGE_LOGD("Crop IN");
3297 if (!prepareNapiEnv(env, info, &nVal)) {
3298 return nVal.result;
3299 }
3300 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3301
3302 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
3303 IMAGE_LOGE("Invalid args count");
3304 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3305 } else {
3306 if (!parseRegion(env, nVal.argv[NUM_0], &(nVal.context->area.region))) {
3307 IMAGE_LOGE("Region type mismatch");
3308 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3309 }
3310 }
3311 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
3312 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
3313 }
3314
3315 if (nVal.context->callbackRef == nullptr) {
3316 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
3317 }
3318 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
3319 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . Crop failed",
3320 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "CropGeneralError",
3321 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
3322 nVal.result);
3323 napi_value _resource = nullptr;
3324 napi_create_string_utf8(env, "CropExec", NAPI_AUTO_LENGTH, &_resource);
3325 nVal.status = napi_create_async_work(env, nullptr, _resource,
3326 [](napi_env env, void *data) {
3327 auto context = static_cast<PixelMapAsyncContext*>(data);
3328 CropExec(env, context);
3329 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
3330
3331 if (nVal.status == napi_ok) {
3332 nVal.status = napi_queue_async_work(env, nVal.context->work);
3333 if (nVal.status == napi_ok) {
3334 nVal.context.release();
3335 }
3336 }
3337 return nVal.result;
3338 }
3339
CropSync(napi_env env,napi_callback_info info)3340 napi_value PixelMapNapi::CropSync(napi_env env, napi_callback_info info)
3341 {
3342 napi_value result = nullptr;
3343 napi_get_undefined(env, &result);
3344 napi_status napiStatus;
3345 uint32_t status = SUCCESS;
3346 napi_value thisVar = nullptr;
3347 size_t argCount = NUM_1;
3348 napi_value argValue[NUM_1] = {0};
3349 Rect region;
3350
3351 IMAGE_LOGD("CropSync IN");
3352 IMG_JS_ARGS(env, info, napiStatus, argCount, argValue, thisVar);
3353 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(napiStatus), result, IMAGE_LOGE("fail to napi_get_cb_info"));
3354 IMG_NAPI_CHECK_RET_D(argCount == NUM_1,
3355 ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER,
3356 "CropSync failed"),
3357 IMAGE_LOGE("CropSync failed, invalid parameter"));
3358 if (!parseRegion(env, argValue[NUM_0], ®ion)) {
3359 IMAGE_LOGE("Region type mismatch");
3360 return result;
3361 }
3362
3363 PixelMapNapi* pixelMapNapi = nullptr;
3364 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
3365
3366 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(napiStatus, pixelMapNapi), result, IMAGE_LOGE("fail to unwrap context"));
3367 IMG_NAPI_CHECK_RET_D(pixelMapNapi->GetPixelNapiEditable(),
3368 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3369 "Pixelmap has crossed threads . CropSync failed"),
3370 IMAGE_LOGE("Pixelmap has crossed threads . CropSync failed"));
3371
3372 if (pixelMapNapi->nativePixelMap_ != nullptr) {
3373 status = pixelMapNapi->nativePixelMap_->crop(region);
3374 if (status != SUCCESS) {
3375 IMAGE_LOGE("CropSync failed");
3376 }
3377 } else {
3378 IMAGE_LOGE("Null native ref");
3379 }
3380 return result;
3381 }
3382
STATIC_COMPLETE_FUNC(ToSdr)3383 STATIC_COMPLETE_FUNC(ToSdr)
3384 {
3385 auto context = static_cast<PixelMapAsyncContext*>(data);
3386 if (context == nullptr) {
3387 IMAGE_LOGE("ToSdrComplete context is nullptr");
3388 return;
3389 }
3390 napi_value result[NUM_2] = {0};
3391 napi_value retVal;
3392 napi_value callback = nullptr;
3393 napi_get_undefined(env, &result[NUM_0]);
3394 napi_get_undefined(env, &result[NUM_1]);
3395
3396 napi_handle_scope scope = nullptr;
3397 napi_open_handle_scope(env, &scope);
3398 if (scope == nullptr) {
3399 IMAGE_LOGE("ToSdrComplete scope is nullptr");
3400 return;
3401 }
3402 if (context->status == SUCCESS) {
3403 napi_value value = nullptr;
3404 napi_get_undefined(env, &value);
3405 result[NUM_1] = value;
3406 } else if (context->status == ERR_MEDIA_INVALID_OPERATION) {
3407 ImageNapiUtils::CreateErrorObj(env, result[NUM_0], context->status, "The pixelmap is not hdr.");
3408 } else if (context->status == IMAGE_RESULT_GET_SURFAC_FAILED) {
3409 ImageNapiUtils::CreateErrorObj(env, result[NUM_0], ERR_MEDIA_INVALID_OPERATION, "Alloc new memory failed.");
3410 } else if (context->status == ERR_RESOURCE_UNAVAILABLE) {
3411 ImageNapiUtils::CreateErrorObj(env, result[NUM_0], ERR_MEDIA_INVALID_OPERATION, "Pixelmap is not editable");
3412 } else {
3413 ImageNapiUtils::CreateErrorObj(env, result[NUM_0], ERR_MEDIA_INVALID_OPERATION, "Internal error.");
3414 }
3415 if (context->deferred) {
3416 if (context->status == SUCCESS) {
3417 napi_resolve_deferred(env, context->deferred, result[NUM_1]);
3418 } else {
3419 napi_reject_deferred(env, context->deferred, result[NUM_0]);
3420 }
3421 } else {
3422 napi_get_reference_value(env, context->callbackRef, &callback);
3423 napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
3424 napi_delete_reference(env, context->callbackRef);
3425 }
3426 napi_delete_async_work(env, context->work);
3427 napi_close_handle_scope(env, scope);
3428 delete context;
3429 context = nullptr;
3430 }
3431
ToSdrExec(napi_env env,PixelMapAsyncContext * context)3432 static void ToSdrExec(napi_env env, PixelMapAsyncContext* context)
3433 {
3434 if (context == nullptr) {
3435 IMAGE_LOGE("ToSdrExec null context");
3436 return;
3437 }
3438 if (!context->nConstructor->GetPixelNapiEditable()) {
3439 IMAGE_LOGE("ToSdrExec pixelmap is not editable");
3440 context->status = ERR_RESOURCE_UNAVAILABLE;
3441 return;
3442 }
3443 if (context->status == SUCCESS) {
3444 if (context->rPixelMap != nullptr) {
3445 context->status = context->rPixelMap->ToSdr();
3446 } else {
3447 IMAGE_LOGE("ToSdrExec null native ref");
3448 context->status = ERR_IMAGE_INIT_ABNORMAL;
3449 }
3450 } else {
3451 IMAGE_LOGI("ToSdrExec has failed. Do nothing");
3452 }
3453 }
3454
ToSdr(napi_env env,napi_callback_info info)3455 napi_value PixelMapNapi::ToSdr(napi_env env, napi_callback_info info)
3456 {
3457 NapiValues nVal;
3458 nVal.argc = NUM_1;
3459 napi_value argValue[NUM_1] = {0};
3460 nVal.argv = argValue;
3461 if (!prepareNapiEnv(env, info, &nVal)) {
3462 IMAGE_LOGI("ToSdr prepare napi env failed");
3463 return nVal.result;
3464 }
3465 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3466 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
3467 napi_value _resource = nullptr;
3468 napi_create_string_utf8(env, "ToSdrExec", NAPI_AUTO_LENGTH, &_resource);
3469 nVal.status = napi_create_async_work(env, nullptr, _resource,
3470 [](napi_env env, void* data) {
3471 auto context = static_cast<PixelMapAsyncContext*>(data);
3472 ToSdrExec(env, context);
3473 }, ToSdrComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
3474
3475 if (nVal.status == napi_ok) {
3476 nVal.status = napi_queue_async_work(env, nVal.context->work);
3477 if (nVal.status == napi_ok) {
3478 nVal.context.release();
3479 }
3480 }
3481 return nVal.result;
3482 }
3483
GetColorSpace(napi_env env,napi_callback_info info)3484 napi_value PixelMapNapi::GetColorSpace(napi_env env, napi_callback_info info)
3485 {
3486 NapiValues nVal;
3487 nVal.argc = NUM_0;
3488 IMAGE_LOGD("GetColorSpace IN");
3489 napi_get_undefined(env, &nVal.result);
3490 if (!prepareNapiEnv(env, info, &nVal)) {
3491 return ImageNapiUtils::ThrowExceptionError(
3492 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
3493 }
3494 if (nVal.argc != NUM_0) {
3495 return ImageNapiUtils::ThrowExceptionError(
3496 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
3497 }
3498 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
3499 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3500 "Pixelmap has crossed threads . GetColorSpace failed"),
3501 IMAGE_LOGE("Pixelmap has crossed threads . GetColorSpace failed"));
3502 #ifdef IMAGE_COLORSPACE_FLAG
3503 if (nVal.context->nConstructor->nativePixelMap_ == nullptr) {
3504 return ImageNapiUtils::ThrowExceptionError(
3505 env, ERR_IMAGE_DATA_ABNORMAL, "Invalid native pixelmap");
3506 }
3507 auto grCS = nVal.context->nConstructor->nativePixelMap_->InnerGetGrColorSpacePtr();
3508 if (grCS == nullptr) {
3509 return ImageNapiUtils::ThrowExceptionError(
3510 env, ERR_IMAGE_DATA_UNSUPPORT, "No colorspace in pixelmap");
3511 }
3512 auto resultValue = ColorManager::CreateJsColorSpaceObject(env, grCS);
3513 nVal.result = reinterpret_cast<napi_value>(resultValue);
3514 #else
3515 return ImageNapiUtils::ThrowExceptionError(
3516 env, ERR_INVALID_OPERATION, "Unsupported operation");
3517 #endif
3518 return nVal.result;
3519 }
3520
SetColorSpace(napi_env env,napi_callback_info info)3521 napi_value PixelMapNapi::SetColorSpace(napi_env env, napi_callback_info info)
3522 {
3523 NapiValues nVal;
3524 nVal.argc = NUM_1;
3525 napi_value argValue[NUM_1] = {0};
3526 nVal.argv = argValue;
3527 IMAGE_LOGD("SetColorSpace IN");
3528 napi_get_undefined(env, &nVal.result);
3529 if (!prepareNapiEnv(env, info, &nVal)) {
3530 return ImageNapiUtils::ThrowExceptionError(
3531 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
3532 }
3533 if (nVal.argc != NUM_1) {
3534 return ImageNapiUtils::ThrowExceptionError(
3535 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
3536 }
3537 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
3538 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3539 "Pixelmap has crossed threads . SetColorSpace failed"),
3540 IMAGE_LOGE("Pixelmap has crossed threads . SetColorSpace failed"));
3541 #ifdef IMAGE_COLORSPACE_FLAG
3542 nVal.context->colorSpace = ColorManager::GetColorSpaceByJSObject(env, nVal.argv[NUM_0]);
3543 if (nVal.context->colorSpace == nullptr) {
3544 return ImageNapiUtils::ThrowExceptionError(
3545 env, ERR_IMAGE_INVALID_PARAMETER, "ColorSpace mismatch");
3546 }
3547 nVal.context->nConstructor->nativePixelMap_->InnerSetColorSpace(*(nVal.context->colorSpace));
3548 #else
3549 return ImageNapiUtils::ThrowExceptionError(
3550 env, ERR_INVALID_OPERATION, "Unsupported operation");
3551 #endif
3552 return nVal.result;
3553 }
3554
Marshalling(napi_env env,napi_callback_info info)3555 napi_value PixelMapNapi::Marshalling(napi_env env, napi_callback_info info)
3556 {
3557 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3558 NapiValues nVal;
3559 nVal.argc = NUM_1;
3560 napi_value argValue[NUM_1] = {0};
3561 nVal.argv = argValue;
3562 IMAGE_LOGD("Marshalling IN");
3563
3564 if (!prepareNapiEnv(env, info, &nVal)) {
3565 return ImageNapiUtils::ThrowExceptionError(
3566 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
3567 }
3568 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3569 if (nVal.context->rPixelMap == nullptr) {
3570 return ImageNapiUtils::ThrowExceptionError(env, ERR_IPC, "marshalling pixel map to parcel failed.");
3571 }
3572 if (nVal.argc != NUM_0 && nVal.argc != NUM_1) {
3573 return ImageNapiUtils::ThrowExceptionError(
3574 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
3575 }
3576 NAPI_MessageSequence *napiSequence = nullptr;
3577 napi_get_cb_info(env, info, &nVal.argc, nVal.argv, nullptr, nullptr);
3578 napi_unwrap(env, nVal.argv[0], reinterpret_cast<void**>(&napiSequence));
3579 auto messageParcel = napiSequence->GetMessageParcel();
3580 if (messageParcel == nullptr) {
3581 return ImageNapiUtils::ThrowExceptionError(
3582 env, ERR_IPC, "marshalling pixel map to parcel failed.");
3583 }
3584 bool st = nVal.context->rPixelMap->Marshalling(*messageParcel);
3585 if (!st) {
3586 return ImageNapiUtils::ThrowExceptionError(
3587 env, ERR_IPC, "marshalling pixel map to parcel failed.");
3588 }
3589 return nVal.result;
3590 #else
3591 napi_value result = nullptr;
3592 return result;
3593 #endif
3594 }
3595
ApplyColorSpaceExec(napi_env env,PixelMapAsyncContext * context)3596 static void ApplyColorSpaceExec(napi_env env, PixelMapAsyncContext* context)
3597 {
3598 if (context == nullptr) {
3599 IMAGE_LOGE("Null context");
3600 return;
3601 }
3602 if (context->status != SUCCESS) {
3603 IMAGE_LOGD("ApplyColorSpace has failed. do nothing");
3604 return;
3605 }
3606 if (context->rPixelMap == nullptr || context->colorSpace == nullptr) {
3607 context->status = ERR_IMAGE_INIT_ABNORMAL;
3608 IMAGE_LOGE("ApplyColorSpace Null native ref");
3609 return;
3610 }
3611 context->status = context->rPixelMap->ApplyColorSpace(*(context->colorSpace));
3612 }
3613
ParseColorSpaceVal(napi_env env,napi_value val,PixelMapAsyncContext * context)3614 static void ParseColorSpaceVal(napi_env env, napi_value val, PixelMapAsyncContext* context)
3615 {
3616 if (context == nullptr) {
3617 IMAGE_LOGE("Null context");
3618 return;
3619 }
3620
3621 #ifdef IMAGE_COLORSPACE_FLAG
3622 context->colorSpace = ColorManager::GetColorSpaceByJSObject(env, val);
3623 if (context->colorSpace == nullptr) {
3624 context->status = ERR_IMAGE_INVALID_PARAMETER;
3625 }
3626 #else
3627 Val.context->status = ERR_IMAGE_DATA_UNSUPPORT;
3628 #endif
3629 }
3630
ApplyColorSpace(napi_env env,napi_callback_info info)3631 napi_value PixelMapNapi::ApplyColorSpace(napi_env env, napi_callback_info info)
3632 {
3633 NapiValues nVal;
3634 nVal.argc = NUM_2;
3635 napi_value argValue[NUM_2] = {0};
3636 nVal.argv = argValue;
3637 IMAGE_LOGD("ApplyColorSpace IN");
3638 if (!prepareNapiEnv(env, info, &nVal)) {
3639 return nVal.result;
3640 }
3641 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3642
3643 if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
3644 IMAGE_LOGE("Invalid args count");
3645 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3646 } else {
3647 ParseColorSpaceVal(env, nVal.argv[NUM_0], nVal.context.get());
3648 }
3649 if (nVal.argc >= NUM_1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
3650 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
3651 }
3652
3653 if (nVal.context->callbackRef == nullptr) {
3654 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
3655 }
3656 IMG_NAPI_CHECK_BUILD_ERROR(nVal.context->nConstructor->GetPixelNapiEditable(),
3657 BuildContextError(env, nVal.context->error, "pixelmap has crossed threads . ApplyColorSpace failed",
3658 ERR_RESOURCE_UNAVAILABLE), IMG_CREATE_CREATE_ASYNC_WORK(env, nVal.status, "ApplyColorSpaceGeneralError",
3659 [](napi_env env, void *data) {}, GeneralErrorComplete, nVal.context, nVal.context->work),
3660 nVal.result);
3661 napi_value _resource = nullptr;
3662 napi_create_string_utf8(env, "ApplyColorSpace", NAPI_AUTO_LENGTH, &_resource);
3663 nVal.status = napi_create_async_work(env, nullptr, _resource, [](napi_env env, void *data) {
3664 auto context = static_cast<PixelMapAsyncContext*>(data);
3665 ApplyColorSpaceExec(env, context);
3666 }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
3667
3668 if (nVal.status == napi_ok) {
3669 nVal.status = napi_queue_async_work(env, nVal.context->work);
3670 if (nVal.status == napi_ok) {
3671 nVal.context.release();
3672 }
3673 }
3674 return nVal.result;
3675 }
3676
IsMatchFormatType(FormatType type,PixelFormat format)3677 static bool IsMatchFormatType(FormatType type, PixelFormat format)
3678 {
3679 if (type == FormatType::YUV) {
3680 switch (format) {
3681 case PixelFormat::NV21:
3682 case PixelFormat::NV12:
3683 case PixelFormat::YCBCR_P010:
3684 case PixelFormat::YCRCB_P010:{
3685 return true;
3686 }
3687 default:{
3688 return false;
3689 }
3690 }
3691 } else if (type == FormatType::RGB) {
3692 switch (format) {
3693 case PixelFormat::ARGB_8888:
3694 case PixelFormat::RGB_565:
3695 case PixelFormat::RGBA_8888:
3696 case PixelFormat::BGRA_8888:
3697 case PixelFormat::RGB_888:
3698 case PixelFormat::RGBA_F16:
3699 case PixelFormat::RGBA_1010102:{
3700 return true;
3701 }
3702 default:{
3703 return false;
3704 }
3705 }
3706 } else {
3707 return false;
3708 }
3709 }
3710
STATIC_EXEC_FUNC(GeneralError)3711 STATIC_EXEC_FUNC(GeneralError)
3712 {
3713 if (data == nullptr) {
3714 IMAGE_LOGE("GeneralErrorExec invalid parameter: data is null");
3715 return;
3716 }
3717 auto context = static_cast<PixelMapAsyncContext*>(data);
3718 context->status = IMAGE_RESULT_CREATE_FORMAT_CONVERT_FAILED;
3719 }
3720
TypeFormat(PixelFormat & pixelForamt)3721 static FormatType TypeFormat(PixelFormat &pixelForamt)
3722 {
3723 switch (pixelForamt) {
3724 case PixelFormat::ARGB_8888:
3725 case PixelFormat::RGB_565:
3726 case PixelFormat::RGBA_8888:
3727 case PixelFormat::BGRA_8888:
3728 case PixelFormat::RGB_888:
3729 case PixelFormat::RGBA_F16:
3730 case PixelFormat::RGBA_1010102:{
3731 return FormatType::RGB;
3732 }
3733 case PixelFormat::NV21:
3734 case PixelFormat::NV12:
3735 case PixelFormat::YCBCR_P010:
3736 case PixelFormat::YCRCB_P010:{
3737 return FormatType::YUV;
3738 }
3739 default:
3740 return FormatType::UNKNOWN;
3741 }
3742 }
3743
GetNativePixelMapInfo(napi_env & env,PixelMapAsyncContext * context)3744 static uint32_t GetNativePixelMapInfo(napi_env &env, PixelMapAsyncContext* context)
3745 {
3746 if (context == nullptr) {
3747 IMAGE_LOGE("GetNativePixelMapInfo invalid parameter: context is null");
3748 return ERROR;
3749 }
3750
3751 PixelFormat destPixelFormat = context->destFormat;
3752 std::shared_ptr<PixelMap> pixelMap = nullptr;
3753 IMG_NAPI_CHECK_BUILD_ERROR(IsMatchFormatType(context->dstFormatType, destPixelFormat),
3754 BuildContextError(env, context->error, "dest format is wrong!", ERR_IMAGE_INVALID_PARAMETER),
3755 context->status = ERR_IMAGE_INVALID_PARAMETER, ERR_IMAGE_INVALID_PARAMETER);
3756 IMG_NAPI_CHECK_BUILD_ERROR(IsMatchFormatType(context->srcFormatType, context->rPixelMap->GetPixelFormat()),
3757 BuildContextError(env, context->error, "source format is wrong!", ERR_IMAGE_INVALID_PARAMETER),
3758 context->status = ERR_IMAGE_INVALID_PARAMETER, ERR_IMAGE_INVALID_PARAMETER);
3759 return SUCCESS;
3760 }
3761
GetNativeConvertInfo(napi_env & env,napi_callback_info & info,PixelMapAsyncContext * context)3762 static uint32_t GetNativeConvertInfo(napi_env &env, napi_callback_info &info, PixelMapAsyncContext* context)
3763 {
3764 if (context == nullptr) {
3765 IMAGE_LOGE("GetNativeConvertInfo invalid parameter: context is null");
3766 return ERROR;
3767 }
3768
3769 napi_status status = napi_invalid_arg;
3770 napi_value thisVar = nullptr;
3771 size_t argc = NUM_1;
3772 napi_value argv[NUM_1] = {nullptr};
3773 IMG_JS_ARGS(env, info, status, argc, argv, thisVar);
3774 IMG_NAPI_CHECK_BUILD_ERROR(IMG_IS_OK(status),
3775 BuildContextError(env, context->error, "fail to napi_get_cb_info", ERROR), context->status = ERROR, ERROR);
3776 IMG_NAPI_CHECK_BUILD_ERROR(argc == NUM_1,
3777 BuildContextError(env, context->error, "incorrect number of parametersarguments!", ERR_IMAGE_INVALID_PARAMETER),
3778 context->status = ERR_IMAGE_INVALID_PARAMETER, ERR_IMAGE_INVALID_PARAMETER);
3779 napi_value constructor = nullptr;
3780 napi_value global = nullptr;
3781 napi_get_global(env, &global);
3782 status = napi_get_named_property(env, global, "PixelFormat", &constructor);
3783 IMG_NAPI_CHECK_BUILD_ERROR(IMG_IS_OK(status),
3784 BuildContextError(env, context->error, "Get PixelMapNapi property failed!", ERR_IMAGE_PROPERTY_NOT_EXIST),
3785 context->status = ERR_IMAGE_PROPERTY_NOT_EXIST, ERR_IMAGE_PROPERTY_NOT_EXIST);
3786
3787 bool isPixelFormat = false;
3788 if (context->destFormat == PixelFormat::UNKNOWN) {
3789 isPixelFormat = false;
3790 } else {
3791 isPixelFormat = true;
3792 }
3793
3794 if (isPixelFormat) {
3795 return GetNativePixelMapInfo(env, context);
3796 }
3797 IMG_NAPI_CHECK_BUILD_ERROR(false,
3798 BuildContextError(env, context->error, "wrong arguments!", ERR_IMAGE_INVALID_PARAMETER),
3799 context->status = ERR_IMAGE_INVALID_PARAMETER, ERR_IMAGE_INVALID_PARAMETER);
3800 }
3801
Convert(napi_env & env,napi_callback_info & info,FormatType srcFormatType,std::string workName,PixelMapAsyncContext * context)3802 static napi_value Convert(napi_env &env, napi_callback_info &info, FormatType srcFormatType, std::string workName,
3803 PixelMapAsyncContext* context)
3804 {
3805 napi_value result = nullptr;
3806 napi_get_undefined(env, &result);
3807 napi_status status;
3808 if (context == nullptr) {
3809 return nullptr;
3810 }
3811 context->status = SUCCESS;
3812 context->srcFormatType = srcFormatType;
3813 uint32_t ret = GetNativeConvertInfo(env, info, context);
3814 napi_create_promise(env, &(context->deferred), &result);
3815 PixelMapAsyncContextPtr asyncContext = std::make_unique<PixelMapAsyncContext>(*context);
3816 IMG_NAPI_CHECK_BUILD_ERROR(asyncContext->error == nullptr,
3817 asyncContext->status = IMAGE_RESULT_CREATE_FORMAT_CONVERT_FAILED,
3818 IMG_CREATE_CREATE_ASYNC_WORK(env, status, (workName + "GeneralError").c_str(),
3819 GeneralErrorExec, GeneralErrorComplete, asyncContext, asyncContext->work),
3820 result);
3821
3822 IMG_NAPI_CHECK_BUILD_ERROR(ret == SUCCESS,
3823 BuildContextError(env, asyncContext->error, "get native convert info failed!", ret),
3824 IMG_CREATE_CREATE_ASYNC_WORK(env, status, (workName + "GeneralError").c_str(),
3825 GeneralErrorExec, GeneralErrorComplete, asyncContext, asyncContext->work),
3826 result);
3827
3828 context->status = ImageFormatConvert::ConvertImageFormat(context->rPixelMap, context->destFormat);
3829 if (context->status == SUCCESS) {
3830 result = PixelMapNapi::CreatePixelMap(env, context->rPixelMap);
3831 return result;
3832 }
3833 return result;
3834 }
3835
YUVToRGB(napi_env env,napi_callback_info & info,PixelMapAsyncContext * context)3836 static napi_value YUVToRGB(napi_env env, napi_callback_info &info, PixelMapAsyncContext* context)
3837 {
3838 return Convert(env, info, FormatType::YUV, "YUVToRGB", context);
3839 }
3840
RGBToYUV(napi_env env,napi_callback_info & info,PixelMapAsyncContext * context)3841 static napi_value RGBToYUV(napi_env env, napi_callback_info &info, PixelMapAsyncContext* context)
3842 {
3843 return Convert(env, info, FormatType::RGB, "RGBToYUV", context);
3844 }
3845
PixelFormatConvert(napi_env env,napi_callback_info & info,PixelMapAsyncContext * context)3846 static napi_value PixelFormatConvert(napi_env env, napi_callback_info &info, PixelMapAsyncContext* context)
3847 {
3848 if (context == nullptr) {
3849 IMAGE_LOGE("PixelFormatConvert invalid parameter: context is null");
3850 return nullptr;
3851 }
3852
3853 napi_value result = nullptr;
3854 napi_create_promise(env, &(context->deferred), &result);
3855 PixelFormat dstFormat = context->destFormat;
3856
3857 if (dstFormat != PixelFormat::UNKNOWN) {
3858 context->dstFormatType = TypeFormat(dstFormat);
3859 if (context->dstFormatType == FormatType::YUV &&
3860 (context->srcFormatType == FormatType::UNKNOWN || context->srcFormatType == FormatType::RGB)) {
3861 result = RGBToYUV(env, info, context);
3862 } else if ((context->dstFormatType == FormatType::RGB) &&
3863 (context->srcFormatType == FormatType::UNKNOWN || context->srcFormatType == FormatType::YUV)) {
3864 result = YUVToRGB(env, info, context);
3865 }
3866 }
3867 return result;
3868 }
3869
ConvertPixelMapFormat(napi_env env,napi_callback_info info)3870 napi_value PixelMapNapi::ConvertPixelMapFormat(napi_env env, napi_callback_info info)
3871 {
3872 NapiValues nVal;
3873 napi_value argValue[NUM_2];
3874 size_t argc = NUM_2;
3875 nVal.argc = argc;
3876 nVal.argv = argValue;
3877
3878 if (!prepareNapiEnv(env, info, &nVal)) {
3879 return nVal.result;
3880 }
3881 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
3882 if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
3883 napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
3884 }
3885
3886 if (!nVal.context) {
3887 return nullptr;
3888 }
3889 napi_get_undefined(env, &nVal.result);
3890 if (nVal.argc != NUM_1) {
3891 IMAGE_LOGE("Invalid args count");
3892 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
3893 }
3894
3895 if (nVal.context->callbackRef == nullptr) {
3896 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
3897 } else {
3898 napi_get_undefined(env, &(nVal.result));
3899 }
3900
3901 napi_value jsArg = nVal.argv[0];
3902 int32_t pixelFormatInt;
3903 napi_get_value_int32(env, jsArg, &pixelFormatInt);
3904 nVal.context->destFormat = static_cast<PixelFormat>(pixelFormatInt);
3905
3906 if (TypeFormat(nVal.context->destFormat) == FormatType::UNKNOWN) {
3907 napi_value errCode = nullptr;
3908 napi_create_int32(env, ERR_IMAGE_INVALID_PARAMETER, &errCode);
3909 napi_reject_deferred(env, nVal.context->deferred, errCode);
3910 IMAGE_LOGE("dstFormat is not support or invalid");
3911 return nVal.result;
3912 }
3913
3914 nVal.result = PixelFormatConvert(env, info, nVal.context.get());
3915 nVal.context->nConstructor->nativePixelMap_ = nVal.context->rPixelMap;
3916 if (nVal.result == nullptr) {
3917 return nVal.result;
3918 }
3919 return nVal.result;
3920 }
3921
SetTransferDetached(napi_env env,napi_callback_info info)3922 napi_value PixelMapNapi::SetTransferDetached(napi_env env, napi_callback_info info)
3923 {
3924 NapiValues nVal;
3925 napi_value argValue[NUM_1];
3926 nVal.argc = NUM_1;
3927 nVal.argv = argValue;
3928 napi_status status = napi_invalid_arg;
3929 napi_get_undefined(env, &nVal.result);
3930 if (!prepareNapiEnv(env, info, &nVal)) {
3931 return ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE, "Fail to unwrap context");
3932 }
3933 bool detach;
3934 status = napi_get_value_bool(env, nVal.argv[NUM_0], &detach);
3935 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
3936 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
3937 "SetTransferDetached get detach failed"),
3938 IMAGE_LOGE("SetTransferDetached get detach failed"));
3939 nVal.context->nConstructor->SetTransferDetach(detach);
3940 return nVal.result;
3941 }
3942 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3943 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
3944 enum HdrMetadataKey : uint32_t {
3945 HDR_METADATA_TYPE = 0,
3946 HDR_STATIC_METADATA,
3947 HDR_DYNAMIC_METADATA,
3948 HDR_GAINMAP_METADATA,
3949 };
3950
3951 enum HdrMetadataType : uint32_t {
3952 NONE = 0,
3953 BASE,
3954 GAINMAP,
3955 ALTERNATE,
3956 INVALID,
3957 };
3958
3959 static std::map<HdrMetadataType, CM_HDR_Metadata_Type> EtsMetadataMap = {
3960 {NONE, CM_METADATA_NONE},
3961 {BASE, CM_IMAGE_HDR_VIVID_DUAL},
3962 {GAINMAP, CM_METADATA_NONE},
3963 {ALTERNATE, CM_IMAGE_HDR_VIVID_SINGLE},
3964 };
3965
3966 static std::map<CM_HDR_Metadata_Type, HdrMetadataType> MetadataEtsMap = {
3967 {CM_METADATA_NONE, NONE},
3968 {CM_IMAGE_HDR_VIVID_DUAL, BASE},
3969 {CM_IMAGE_HDR_VIVID_SINGLE, ALTERNATE},
3970 };
3971
FloatToDouble(float val)3972 static double FloatToDouble(float val)
3973 {
3974 const double precision = 1000000.0;
3975 val *= precision;
3976 double result = static_cast<double>(val / precision);
3977 return result;
3978 }
3979
CreateArrayDouble(napi_env env,napi_value & root,float value,int index)3980 static bool CreateArrayDouble(napi_env env, napi_value &root, float value, int index)
3981 {
3982 napi_value node = nullptr;
3983 if (!CREATE_NAPI_DOUBLE(FloatToDouble(value), node)) {
3984 return false;
3985 }
3986 if (napi_set_element(env, root, index, node) != napi_ok) {
3987 return false;
3988 }
3989 return true;
3990 }
3991
CreateJsNumber(napi_env env,double value)3992 inline napi_value CreateJsNumber(napi_env env, double value)
3993 {
3994 napi_value result = nullptr;
3995 napi_create_double(env, value, &result);
3996 return result;
3997 }
3998
CreateNapiDouble(napi_env env,napi_value & root,float value,std::string name)3999 static bool CreateNapiDouble(napi_env env, napi_value &root, float value, std::string name)
4000 {
4001 napi_value node = CreateJsNumber(env, FloatToDouble(value));
4002 if (napi_set_named_property(env, root, name.c_str(), node) != napi_ok) {
4003 return false;
4004 }
4005 return true;
4006 }
4007
CreateNapiUint32(napi_env env,napi_value & root,int32_t value,std::string name)4008 static bool CreateNapiUint32(napi_env env, napi_value &root, int32_t value, std::string name)
4009 {
4010 napi_value node = nullptr;
4011 if (!CREATE_NAPI_INT32(value, node)) {
4012 return false;
4013 }
4014
4015 if (napi_set_named_property(env, root, name.c_str(), node) != napi_ok) {
4016 return false;
4017 }
4018 return true;
4019 }
4020
CreateNapiBool(napi_env env,napi_value & root,bool value,std::string name)4021 static bool CreateNapiBool(napi_env env, napi_value &root, bool value, std::string name)
4022 {
4023 napi_value node = nullptr;
4024 if (napi_get_boolean(env, value, &node) != napi_ok) {
4025 return false;
4026 }
4027 if (napi_set_named_property(env, root, name.c_str(), node) != napi_ok) {
4028 return false;
4029 }
4030 return true;
4031 }
BuildStaticMetadataNapi(napi_env env,HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata & staticMetadata)4032 static napi_value BuildStaticMetadataNapi(napi_env env,
4033 HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata &staticMetadata)
4034 {
4035 napi_value metadataValue = nullptr;
4036 napi_create_object(env, &metadataValue);
4037 napi_value displayPrimariesX = nullptr;
4038 napi_create_array_with_length(env, NUM_3, &displayPrimariesX);
4039 bool status = true;
4040 status &= CreateArrayDouble(env, displayPrimariesX, staticMetadata.smpte2086.displayPrimaryRed.x, NUM_0);
4041 status &= CreateArrayDouble(env, displayPrimariesX, staticMetadata.smpte2086.displayPrimaryGreen.x, NUM_1);
4042 status &= CreateArrayDouble(env, displayPrimariesX, staticMetadata.smpte2086.displayPrimaryBlue.x, NUM_2);
4043 status &= napi_set_named_property(env, metadataValue, "displayPrimariesX", displayPrimariesX) == napi_ok;
4044 napi_value displayPrimariesY = nullptr;
4045 napi_create_array_with_length(env, NUM_3, &displayPrimariesY);
4046 status &= CreateArrayDouble(env, displayPrimariesY, staticMetadata.smpte2086.displayPrimaryRed.y, NUM_0);
4047 status &= CreateArrayDouble(env, displayPrimariesY, staticMetadata.smpte2086.displayPrimaryGreen.y, NUM_1);
4048 status &= CreateArrayDouble(env, displayPrimariesY, staticMetadata.smpte2086.displayPrimaryBlue.y, NUM_2);
4049 status &= napi_set_named_property(env, metadataValue, "displayPrimariesY", displayPrimariesY) == napi_ok;
4050 status &= CreateNapiDouble(env, metadataValue, staticMetadata.smpte2086.whitePoint.x, "whitePointX");
4051 status &= CreateNapiDouble(env, metadataValue, staticMetadata.smpte2086.whitePoint.y, "whitePointY");
4052 status &= CreateNapiDouble(env, metadataValue, staticMetadata.smpte2086.maxLuminance, "maxLuminance");
4053 status &= CreateNapiDouble(env, metadataValue, staticMetadata.smpte2086.minLuminance, "minLuminance");
4054 status &= CreateNapiDouble(env, metadataValue,
4055 staticMetadata.cta861.maxContentLightLevel, "maxContentLightLevel");
4056 status &= CreateNapiDouble(env, metadataValue,
4057 staticMetadata.cta861.maxFrameAverageLightLevel, "maxFrameAverageLightLevel");
4058 if (!status) {
4059 IMAGE_LOGD("BuildStaticMetadataNapi failed");
4060 }
4061 return metadataValue;
4062 }
4063
BuildGainmapChannel(napi_env env,napi_value & root,HDRVividExtendMetadata & gainmapMetadata,int index)4064 static bool BuildGainmapChannel(napi_env env, napi_value &root, HDRVividExtendMetadata & gainmapMetadata, int index)
4065 {
4066 bool status = true;
4067 status &= CreateNapiDouble(env, root,
4068 gainmapMetadata.metaISO.enhanceClippedThreholdMaxGainmap[index], "gainmapMax");
4069 status &= CreateNapiDouble(env, root,
4070 gainmapMetadata.metaISO.enhanceClippedThreholdMinGainmap[index], "gainmapMin");
4071 status &= CreateNapiDouble(env, root,
4072 gainmapMetadata.metaISO.enhanceMappingGamma[index], "gamma");
4073 status &= CreateNapiDouble(env, root,
4074 gainmapMetadata.metaISO.enhanceMappingBaselineOffset[index], "baseOffset");
4075 status &= CreateNapiDouble(env, root,
4076 gainmapMetadata.metaISO.enhanceMappingAlternateOffset[index], "alternateOffset");
4077 return status;
4078 }
4079
BuildDynamicMetadataNapi(napi_env env,HDRVividExtendMetadata & gainmapMetadata)4080 static napi_value BuildDynamicMetadataNapi(napi_env env, HDRVividExtendMetadata &gainmapMetadata)
4081 {
4082 napi_value metadataValue = nullptr;
4083 napi_create_object(env, &metadataValue);
4084 bool status = true;
4085 status &= CreateNapiUint32(env, metadataValue, static_cast<int32_t>(
4086 gainmapMetadata.metaISO.writeVersion), "writerVersion");
4087 status &= CreateNapiUint32(env, metadataValue, static_cast<int32_t>(
4088 gainmapMetadata.metaISO.miniVersion), "miniVersion");
4089 status &= CreateNapiUint32(env, metadataValue, static_cast<int32_t>(
4090 gainmapMetadata.metaISO.gainmapChannelNum), "gainmapChannelCount");
4091 status &= CreateNapiBool(env, metadataValue, static_cast<bool>(
4092 gainmapMetadata.metaISO.useBaseColorFlag), "useBaseColorFlag");
4093 status &= CreateNapiDouble(env, metadataValue, gainmapMetadata.metaISO.baseHeadroom, "baseHeadroom");
4094 status &= CreateNapiDouble(env, metadataValue, gainmapMetadata.metaISO.alternateHeadroom, "alternateHeadroom");
4095 napi_value array = nullptr;
4096 napi_create_object(env, &array);
4097 for (uint32_t i = 0; i < NUM_3; i++) {
4098 napi_value gainmapChannel = nullptr;
4099 napi_create_object(env, &gainmapChannel);
4100 status &= BuildGainmapChannel(env, gainmapChannel, gainmapMetadata, i);
4101 napi_set_element(env, array, i, gainmapChannel);
4102 }
4103 napi_set_named_property(env, metadataValue, "channels", array);
4104 if (!status) {
4105 IMAGE_LOGD("BuildDynamicMetadataNapi failed");
4106 }
4107 return metadataValue;
4108 }
4109
GetStaticMetadata(napi_env env,OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer,napi_value & metadataValue)4110 static napi_status GetStaticMetadata(napi_env env, OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer,
4111 napi_value &metadataValue)
4112 {
4113 HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata staticMetadata;
4114 uint32_t vecSize = sizeof(HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata);
4115 std::vector<uint8_t> staticData;
4116 if (!VpeUtils::GetSbStaticMetadata(surfaceBuffer, staticData) ||
4117 (staticData.size() != vecSize)) {
4118 IMAGE_LOGE("GetSbStaticMetadata failed");
4119 return napi_invalid_arg;
4120 }
4121 if (memcpy_s(&staticMetadata, vecSize, staticData.data(), staticData.size()) != EOK) {
4122 return napi_invalid_arg;
4123 }
4124 metadataValue = BuildStaticMetadataNapi(env, staticMetadata);
4125 return napi_ok;
4126 }
4127
GetDynamicMetadata(napi_env env,OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer,napi_value & metadataValue)4128 static napi_status GetDynamicMetadata(napi_env env,
4129 OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer, napi_value &metadataValue)
4130 {
4131 std::vector<uint8_t> dynamicData;
4132 if (VpeUtils::GetSbDynamicMetadata(surfaceBuffer, dynamicData) && (dynamicData.size() > 0)) {
4133 napi_value result = nullptr;
4134 napi_get_undefined(env, &result);
4135 ImageNapiUtils::CreateArrayBuffer(env, dynamicData.data(), dynamicData.size(), &result);
4136 metadataValue = result;
4137 if (metadataValue == nullptr) {
4138 return napi_invalid_arg;
4139 }
4140 return napi_ok;
4141 }
4142 IMAGE_LOGE("GetSbDynamicMetadata failed");
4143 return napi_invalid_arg;
4144 }
4145
GetMetadataType(napi_env env,OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer,napi_value & metadataValue)4146 static napi_status GetMetadataType(napi_env env,
4147 OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer, napi_value &metadataValue)
4148 {
4149 CM_HDR_Metadata_Type type;
4150 VpeUtils::GetSbMetadataType(surfaceBuffer, type);
4151 if (MetadataEtsMap.find(type) != MetadataEtsMap.end()) {
4152 int32_t value = static_cast<int32_t>(MetadataEtsMap[type]);
4153 std::vector<uint8_t> gainmapData;
4154 if (type == CM_HDR_Metadata_Type::CM_METADATA_NONE &&
4155 VpeUtils::GetSbDynamicMetadata(surfaceBuffer, gainmapData) &&
4156 gainmapData.size() == sizeof(HDRVividExtendMetadata)) {
4157 value = static_cast<int32_t>(HdrMetadataType::GAINMAP);
4158 }
4159 if (!CREATE_NAPI_INT32(value, metadataValue)) {
4160 return napi_invalid_arg;
4161 }
4162 return napi_ok;
4163 }
4164 IMAGE_LOGE("GetMetadataType failed");
4165 return napi_invalid_arg;
4166 }
4167
BuildHdrMetadataValue(napi_env env,napi_value argv[],std::shared_ptr<PixelMap> pixelMap,napi_value & metadataValue)4168 static napi_status BuildHdrMetadataValue(napi_env env, napi_value argv[],
4169 std::shared_ptr<PixelMap> pixelMap, napi_value &metadataValue)
4170 {
4171 uint32_t metadataKey = 0;
4172 napi_get_value_uint32(env, argv[NUM_0], &metadataKey);
4173 OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer(
4174 reinterpret_cast<OHOS::SurfaceBuffer*>(pixelMap->GetFd()));
4175 switch (HdrMetadataKey(metadataKey)) {
4176 case HDR_METADATA_TYPE:
4177 return GetMetadataType(env, surfaceBuffer, metadataValue);
4178 break;
4179 case HDR_STATIC_METADATA:
4180 return GetStaticMetadata(env, surfaceBuffer, metadataValue);
4181 break;
4182 case HDR_DYNAMIC_METADATA:
4183 return GetDynamicMetadata(env, surfaceBuffer, metadataValue);
4184 break;
4185 case HDR_GAINMAP_METADATA:
4186 {
4187 std::vector<uint8_t> gainmapData;
4188 if (VpeUtils::GetSbDynamicMetadata(surfaceBuffer, gainmapData) &&
4189 (gainmapData.size() == sizeof(HDRVividExtendMetadata))) {
4190 HDRVividExtendMetadata &gainmapMetadata =
4191 *(reinterpret_cast<HDRVividExtendMetadata*>(gainmapData.data()));
4192 metadataValue = BuildDynamicMetadataNapi(env, gainmapMetadata);
4193 return napi_ok;
4194 }
4195 IMAGE_LOGE("GetSbDynamicMetadata failed");
4196 }
4197 break;
4198 default:
4199 break;
4200 }
4201 return napi_invalid_arg;
4202 }
4203
GetMetadata(napi_env env,napi_callback_info info)4204 napi_value PixelMapNapi::GetMetadata(napi_env env, napi_callback_info info)
4205 {
4206 NapiValues nVal;
4207 napi_value argValue[NUM_1];
4208 nVal.argc = NUM_1;
4209 nVal.argv = argValue;
4210 nVal.status = napi_invalid_arg;
4211 if (!prepareNapiEnv(env, info, &nVal) || !nVal.context || !nVal.context->nConstructor ||
4212 !nVal.context->nConstructor->nativePixelMap_) {
4213 return ImageNapiUtils::ThrowExceptionError(env, COMMON_ERR_INVALID_PARAMETER, "Fail to unwrap context");
4214 }
4215 std::shared_ptr<PixelMap> pixelMap = nVal.context->nConstructor->nativePixelMap_;
4216 if (pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
4217 return ImageNapiUtils::ThrowExceptionError(env, ERR_DMA_NOT_EXIST, "Not DMA memory");
4218 }
4219
4220 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
4221 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
4222 "Pixelmap has crossed threads . GetMetadata failed"),
4223 IMAGE_LOGE("Pixelmap has crossed threads . GetMetadata failed"));
4224 nVal.status = BuildHdrMetadataValue(env, nVal.argv, pixelMap, nVal.result);
4225 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(nVal.status),
4226 ImageNapiUtils::ThrowExceptionError(env, ERR_MEMORY_COPY_FAILED,
4227 "BuildHdrMetadataValue failed"),
4228 IMAGE_LOGE("BuildHdrMetadataValue failed"));
4229 return nVal.result;
4230 }
4231
ParseHdrMetadataType(napi_env env,napi_value & hdrMetadataType)4232 static HdrMetadataType ParseHdrMetadataType(napi_env env, napi_value &hdrMetadataType)
4233 {
4234 uint32_t type = 0;
4235 napi_get_value_uint32(env, hdrMetadataType, &type);
4236 if (type < HdrMetadataType::INVALID && type >= HdrMetadataType::NONE) {
4237 return HdrMetadataType(type);
4238 }
4239 return HdrMetadataType::INVALID;
4240 }
4241
ParseArrayDoubleNode(napi_env env,napi_value & root,std::vector<float> & vec)4242 static bool ParseArrayDoubleNode(napi_env env, napi_value &root, std::vector<float> &vec)
4243 {
4244 uint32_t vecSize = 0;
4245 napi_get_array_length(env, root, &vecSize);
4246 if (vecSize > 0) {
4247 for (uint32_t i = 0; i < NUM_3; i++) {
4248 napi_value tempDiv = nullptr;
4249 napi_get_element(env, root, i, &tempDiv);
4250 double gamma = 0.0f;
4251 if (napi_get_value_double(env, tempDiv, &gamma) != napi_ok) {
4252 IMAGE_LOGD("ParseArrayDoubleNode get value failed");
4253 return false;
4254 }
4255 vec.emplace_back((float)gamma);
4256 }
4257 return true;
4258 }
4259 return false;
4260 }
4261
ParseDoubleMetadataNode(napi_env env,napi_value & root,std::string name,float & value)4262 static bool ParseDoubleMetadataNode(napi_env env, napi_value &root,
4263 std::string name, float &value)
4264 {
4265 double ret = 0.0;
4266 if (!GET_DOUBLE_BY_NAME(root, name.c_str(), ret)) {
4267 IMAGE_LOGI("parse %{public}s failed", name.c_str());
4268 return false;
4269 }
4270 value = static_cast<float>(ret);
4271 return true;
4272 }
4273
ParseStaticMetadata(napi_env env,napi_value & hdrStaticMetadata,std::vector<uint8_t> & staticMetadataVec)4274 static bool ParseStaticMetadata(napi_env env, napi_value &hdrStaticMetadata, std::vector<uint8_t> &staticMetadataVec)
4275 {
4276 HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata staticMetadata{};
4277 napi_value displayX = nullptr;
4278 std::vector<float> displayPrimariesX;
4279 if (!GET_NODE_BY_NAME(hdrStaticMetadata, "displayPrimariesX", displayX)) {
4280 IMAGE_LOGI("parse displayPrimariesX failed");
4281 }
4282 if (!ParseArrayDoubleNode(env, displayX, displayPrimariesX)) {
4283 IMAGE_LOGI("parse array y failed");
4284 }
4285 std::vector<float> displayPrimariesY;
4286 napi_value displayY = nullptr;
4287 if (!GET_NODE_BY_NAME(hdrStaticMetadata, "displayPrimariesY", displayY)) {
4288 IMAGE_LOGI("parse displayPrimariesY failed");
4289 }
4290 if (!ParseArrayDoubleNode(env, displayY, displayPrimariesY)) {
4291 IMAGE_LOGI("parse array y failed");
4292 }
4293 staticMetadata.smpte2086.displayPrimaryRed.x = displayPrimariesX[NUM_0];
4294 staticMetadata.smpte2086.displayPrimaryRed.y = displayPrimariesY[NUM_0];
4295 staticMetadata.smpte2086.displayPrimaryGreen.x = displayPrimariesX[NUM_1];
4296 staticMetadata.smpte2086.displayPrimaryGreen.y = displayPrimariesY[NUM_1];
4297 staticMetadata.smpte2086.displayPrimaryBlue.x = displayPrimariesX[NUM_2];
4298 staticMetadata.smpte2086.displayPrimaryBlue.y = displayPrimariesY[NUM_2];
4299 ParseDoubleMetadataNode(env, hdrStaticMetadata, "whitePointX", staticMetadata.smpte2086.whitePoint.x);
4300 ParseDoubleMetadataNode(env, hdrStaticMetadata, "whitePointY", staticMetadata.smpte2086.whitePoint.y);
4301 ParseDoubleMetadataNode(env, hdrStaticMetadata, "maxLuminance", staticMetadata.smpte2086.maxLuminance);
4302 ParseDoubleMetadataNode(env, hdrStaticMetadata, "minLuminance", staticMetadata.smpte2086.minLuminance);
4303 ParseDoubleMetadataNode(env, hdrStaticMetadata, "maxContentLightLevel",
4304 staticMetadata.cta861.maxContentLightLevel);
4305 ParseDoubleMetadataNode(env, hdrStaticMetadata, "maxFrameAverageLightLevel",
4306 staticMetadata.cta861.maxFrameAverageLightLevel);
4307 uint32_t vecSize = sizeof(HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata);
4308 if (memcpy_s(staticMetadataVec.data(), vecSize, &staticMetadata, vecSize) != EOK) {
4309 IMAGE_LOGI("staticMetadataVec memcpy failed");
4310 return false;
4311 }
4312 return true;
4313 }
4314
ParseDynamicMetadata(napi_env env,napi_value & root,std::vector<uint8_t> & dynamicMetadataVec)4315 static bool ParseDynamicMetadata(napi_env env, napi_value &root, std::vector<uint8_t> &dynamicMetadataVec)
4316 {
4317 void *buffer = nullptr;
4318 size_t size;
4319 if (napi_get_arraybuffer_info(env, root, &buffer, &size) != napi_ok) {
4320 return false;
4321 }
4322 dynamicMetadataVec.resize(size);
4323 if (memcpy_s(dynamicMetadataVec.data(), size, buffer, size) != EOK) {
4324 return false;
4325 }
4326 return true;
4327 }
4328
ParseGainmapChannel(napi_env env,napi_value & root,HDRVividExtendMetadata & extendMetadata,int index)4329 static bool ParseGainmapChannel(napi_env env, napi_value &root, HDRVividExtendMetadata &extendMetadata, int index)
4330 {
4331 if (!ParseDoubleMetadataNode(env, root, "gainmapMax",
4332 extendMetadata.metaISO.enhanceClippedThreholdMaxGainmap[index])) {
4333 return false;
4334 }
4335 if (!ParseDoubleMetadataNode(env, root, "gainmapMin",
4336 extendMetadata.metaISO.enhanceClippedThreholdMinGainmap[index])) {
4337 return false;
4338 }
4339 if (!ParseDoubleMetadataNode(env, root, "gamma", extendMetadata.metaISO.enhanceMappingGamma[index])) {
4340 return false;
4341 }
4342 if (!ParseDoubleMetadataNode(env, root, "baseOffset", extendMetadata.metaISO.enhanceMappingBaselineOffset[index])) {
4343 return false;
4344 }
4345 if (!ParseDoubleMetadataNode(env, root, "alternateOffset",
4346 extendMetadata.metaISO.enhanceMappingAlternateOffset[index])) {
4347 return false;
4348 }
4349 return true;
4350 }
4351
ParseGainmapNode(napi_env env,napi_value & root,HDRVividExtendMetadata & extendMetadata)4352 static void ParseGainmapNode(napi_env env, napi_value &root, HDRVividExtendMetadata &extendMetadata)
4353 {
4354 uint32_t isoMetadata = 0;
4355 if (!GET_UINT32_BY_NAME(root, "writerVersion", isoMetadata)) {
4356 IMAGE_LOGI("ParseGainmapNode parse writerVersion failed");
4357 }
4358 extendMetadata.metaISO.writeVersion = static_cast<unsigned short>(isoMetadata);
4359 if (!GET_UINT32_BY_NAME(root, "miniVersion", isoMetadata)) {
4360 IMAGE_LOGI("ParseGainmapNode parse miniVersion failed");
4361 }
4362 extendMetadata.metaISO.miniVersion = static_cast<unsigned short>(isoMetadata);
4363 if (!GET_UINT32_BY_NAME(root, "gainmapChannelCount", isoMetadata)) {
4364 IMAGE_LOGI("ParseGainmapNode parse gainmapChannelCount failed");
4365 }
4366 extendMetadata.metaISO.gainmapChannelNum = static_cast<unsigned char>(isoMetadata);
4367 bool colorflag = false;
4368 if (!GET_BOOL_BY_NAME(root, "useBaseColorFlag", colorflag)) {
4369 IMAGE_LOGI("ParseGainmapNode parse useBaseColorFlag failed");
4370 }
4371 extendMetadata.metaISO.useBaseColorFlag = static_cast<unsigned char>(colorflag);
4372 if (!ParseDoubleMetadataNode(env, root, "baseHeadroom", extendMetadata.metaISO.baseHeadroom)) {
4373 return;
4374 }
4375 if (!ParseDoubleMetadataNode(env, root, "alternateHeadroom", extendMetadata.metaISO.alternateHeadroom)) {
4376 return;
4377 }
4378 napi_value gainmap = nullptr;
4379 if (!GET_NODE_BY_NAME(root, "channels", gainmap)) {
4380 return;
4381 }
4382 bool isArray = false;
4383 napi_is_array(env, gainmap, &isArray);
4384 if (gainmap == nullptr || !isArray) {
4385 return;
4386 }
4387 uint32_t vecSize = 0;
4388 napi_get_array_length(env, gainmap, &vecSize);
4389 if (vecSize <= 0) {
4390 return;
4391 }
4392 for (uint32_t i = 0; i < NUM_3; i++) {
4393 napi_value tempDiv = nullptr;
4394 napi_get_element(env, gainmap, i, &tempDiv);
4395 ParseGainmapChannel(env, tempDiv, extendMetadata, i);
4396 }
4397 return;
4398 }
4399
ParseGainmapMetedata(napi_env env,OHOS::Media::PixelMap & pixelmap,napi_value & root,std::vector<uint8_t> & gainmapMetadataVec)4400 static bool ParseGainmapMetedata(napi_env env, OHOS::Media::PixelMap &pixelmap,
4401 napi_value &root, std::vector<uint8_t> &gainmapMetadataVec)
4402 {
4403 HDRVividExtendMetadata extendMetadata;
4404 #ifdef IMAGE_COLORSPACE_FLAG
4405 OHOS::ColorManager::ColorSpace colorSpace = pixelmap.InnerGetGrColorSpace();
4406 uint16_t SS = ColorUtils::GetPrimaries(colorSpace.GetColorSpaceName());
4407 #else
4408 uint16_t SS = 0;
4409 #endif
4410 extendMetadata.baseColorMeta.baseColorPrimary = SS;
4411 bool colorflag = false;
4412 if (GET_BOOL_BY_NAME(root, "useBaseColorFlag", colorflag)) {
4413 extendMetadata.gainmapColorMeta.combineColorPrimary = colorflag ? SS : (uint8_t)CM_BT2020_HLG_FULL;
4414 extendMetadata.gainmapColorMeta.enhanceDataColorModel = colorflag ? SS : (uint8_t)CM_BT2020_HLG_FULL;
4415 extendMetadata.gainmapColorMeta.alternateColorPrimary = (uint8_t)CM_BT2020_HLG_FULL;
4416 }
4417 ParseGainmapNode(env, root, extendMetadata);
4418 uint32_t vecSize = sizeof(HDRVividExtendMetadata);
4419 if (memcpy_s(gainmapMetadataVec.data(), vecSize, &extendMetadata, vecSize) != EOK) {
4420 IMAGE_LOGE("ParseGainmapMetedata memcpy failed");
4421 return false;
4422 }
4423 return true;
4424 }
4425
SetStaticMetadata(napi_env env,napi_value hdrMetadataValue,OHOS::sptr<OHOS::SurfaceBuffer> & surfaceBuffer)4426 static napi_status SetStaticMetadata(napi_env env, napi_value hdrMetadataValue,
4427 OHOS::sptr<OHOS::SurfaceBuffer> &surfaceBuffer)
4428 {
4429 uint32_t vecSize = sizeof(HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata);
4430 std::vector<uint8_t> metadataVec(vecSize);
4431 if (!ParseStaticMetadata(env, hdrMetadataValue, metadataVec)) {
4432 return napi_invalid_arg;
4433 }
4434 if (!VpeUtils::SetSbStaticMetadata(surfaceBuffer, metadataVec)) {
4435 IMAGE_LOGE("SetSbStaticMetadata failed");
4436 return napi_invalid_arg;
4437 }
4438 return napi_ok;
4439 }
4440
ParseHdrMetadataValue(napi_env env,napi_value argv[],std::shared_ptr<PixelMap> pixelMap)4441 static napi_status ParseHdrMetadataValue(napi_env env, napi_value argv[],
4442 std::shared_ptr<PixelMap> pixelMap)
4443 {
4444 uint32_t metadataKey = 0;
4445 napi_get_value_uint32(env, argv[0], &metadataKey);
4446 napi_value &hdrMetadataValue = argv[NUM_1];
4447 OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer(
4448 reinterpret_cast<OHOS::SurfaceBuffer*>(pixelMap->GetFd()));
4449 switch (HdrMetadataKey(metadataKey)) {
4450 case HDR_METADATA_TYPE:
4451 {
4452 HdrMetadataType type = ParseHdrMetadataType(env, hdrMetadataValue);
4453 if (EtsMetadataMap.find(type) != EtsMetadataMap.end()) {
4454 VpeUtils::SetSbMetadataType(surfaceBuffer, EtsMetadataMap[type]);
4455 } else {
4456 IMAGE_LOGE("SetSbMetadataType failed");
4457 return napi_invalid_arg;
4458 }
4459 }
4460 break;
4461 case HDR_STATIC_METADATA:
4462 return SetStaticMetadata(env, hdrMetadataValue, surfaceBuffer);
4463 break;
4464 case HDR_DYNAMIC_METADATA:
4465 {
4466 std::vector<uint8_t> dynamicMetadataVec;
4467 if (!ParseDynamicMetadata(env, hdrMetadataValue, dynamicMetadataVec)) {
4468 return napi_invalid_arg;
4469 }
4470 if (!VpeUtils::SetSbDynamicMetadata(surfaceBuffer, dynamicMetadataVec)) {
4471 return napi_invalid_arg;
4472 }
4473 }
4474 break;
4475 case HDR_GAINMAP_METADATA:
4476 {
4477 std::vector<uint8_t> gainmapMetadataVec(sizeof(HDRVividExtendMetadata));
4478 if (!ParseGainmapMetedata(env, *(pixelMap.get()), hdrMetadataValue, gainmapMetadataVec)) {
4479 return napi_invalid_arg;
4480 }
4481 if (!VpeUtils::SetSbDynamicMetadata(surfaceBuffer, gainmapMetadataVec)) {
4482 return napi_invalid_arg;
4483 }
4484 }
4485 break;
4486 default:
4487 return napi_invalid_arg;
4488 }
4489 return napi_ok;
4490 }
4491
SetMetadataSync(napi_env env,napi_callback_info info)4492 napi_value PixelMapNapi::SetMetadataSync(napi_env env, napi_callback_info info)
4493 {
4494 IMAGE_LOGD("SetMetadataSync IN");
4495 NapiValues nVal;
4496 nVal.argc = NUM_2;
4497 napi_value argValue[NUM_2] = {0};
4498 nVal.argv = argValue;
4499 nVal.status = napi_invalid_arg;
4500 napi_get_undefined(env, &nVal.result);
4501 if (!prepareNapiEnv(env, info, &nVal)) {
4502 return ImageNapiUtils::ThrowExceptionError(
4503 env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
4504 }
4505 if (nVal.argc != NUM_2) {
4506 return ImageNapiUtils::ThrowExceptionError(
4507 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
4508 }
4509 uint32_t metadataKey = 0;
4510 napi_get_value_uint32(env, argValue[NUM_0], &metadataKey);
4511 if (metadataKey != 0 && ImageNapiUtils::getType(env, argValue[NUM_1]) != napi_object) {
4512 return ImageNapiUtils::ThrowExceptionError(
4513 env, ERR_IMAGE_INVALID_PARAMETER, "Invalid parameter");
4514 }
4515 std::shared_ptr<PixelMap> pixelMap = nVal.context->nConstructor->nativePixelMap_;
4516 if (pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
4517 return ImageNapiUtils::ThrowExceptionError(
4518 env, ERR_DMA_NOT_EXIST, "Not DMA memory");
4519 }
4520
4521 IMG_NAPI_CHECK_RET_D(nVal.context->nConstructor->GetPixelNapiEditable(),
4522 ImageNapiUtils::ThrowExceptionError(env, ERR_RESOURCE_UNAVAILABLE,
4523 "Pixelmap has crossed threads . SetColorSpace failed"),
4524 IMAGE_LOGE("Pixelmap has crossed threads . SetColorSpace failed"));
4525 nVal.status = ParseHdrMetadataValue(env, nVal.argv, pixelMap);
4526 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(nVal.status),
4527 ImageNapiUtils::ThrowExceptionError(env, ERR_MEMORY_COPY_FAILED,
4528 "ParseHdrMetadataValue failed"),
4529 IMAGE_LOGE("ParseHdrMetadataValue failed"));
4530 return nVal.result;
4531 }
4532
SetMetadata(napi_env env,napi_callback_info info)4533 napi_value PixelMapNapi::SetMetadata(napi_env env, napi_callback_info info)
4534 {
4535 IMAGE_LOGD("SetMetadataSync IN");
4536 NapiValues nVal;
4537 nVal.argc = NUM_2;
4538 napi_value argValue[NUM_2] = {0};
4539 nVal.argv = argValue;
4540 nVal.status = napi_ok;
4541 napi_status status;
4542 napi_get_undefined(env, &nVal.result);
4543 if (!prepareNapiEnv(env, info, &nVal)) {
4544 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
4545 }
4546 if (nVal.argc != NUM_2) {
4547 IMAGE_LOGE("Invalid args count");
4548 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
4549 }
4550 uint32_t metadataKey = 0;
4551 napi_get_value_uint32(env, argValue[NUM_0], &metadataKey);
4552 if (metadataKey != 0 && ImageNapiUtils::getType(env, argValue[NUM_1]) != napi_object) {
4553 IMAGE_LOGE("Invalid parameter");
4554 nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
4555 }
4556 nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
4557 if (nVal.context->rPixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
4558 nVal.context->status = ERR_DMA_NOT_EXIST;
4559 }
4560 if (nVal.context->status == napi_ok) {
4561 nVal.status = ParseHdrMetadataValue(env, nVal.argv, nVal.context->rPixelMap);
4562 if (nVal.status != napi_ok) {
4563 nVal.context->status = ERR_MEMORY_COPY_FAILED;
4564 }
4565 }
4566 napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
4567 if (!nVal.context->nConstructor->GetPixelNapiEditable()) {
4568 nVal.context->status = ERR_RESOURCE_UNAVAILABLE;
4569 IMAGE_LOGE("Pixelmap has crossed threads . SetColorSpace failed");
4570 }
4571 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "SetMetadata",
4572 [](napi_env env, void *data) {
4573 }, EmptyResultComplete, nVal.context, nVal.context->work);
4574 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
4575 nullptr, IMAGE_LOGE("fail to create async work"));
4576 return nVal.result;
4577 }
4578 #else
SetMetadata(napi_env env,napi_callback_info info)4579 napi_value PixelMapNapi::SetMetadata(napi_env env, napi_callback_info info)
4580 {
4581 NapiValues nVal;
4582 napi_get_undefined(env, &nVal.result);
4583 return nVal.result;
4584 }
SetMetadataSync(napi_env env,napi_callback_info info)4585 napi_value PixelMapNapi::SetMetadataSync(napi_env env, napi_callback_info info)
4586 {
4587 NapiValues nVal;
4588 napi_get_undefined(env, &nVal.result);
4589 return nVal.result;
4590 }
GetMetadata(napi_env env,napi_callback_info info)4591 napi_value PixelMapNapi::GetMetadata(napi_env env, napi_callback_info info)
4592 {
4593 NapiValues nVal;
4594 napi_get_undefined(env, &nVal.result);
4595 return nVal.result;
4596 }
4597 #endif
4598
release()4599 void PixelMapNapi::release()
4600 {
4601 if (!isRelease) {
4602 if (nativePixelMap_ != nullptr) {
4603 nativePixelMap_.reset();
4604 }
4605 isRelease = true;
4606 }
4607 }
4608 } // namespace Media
4609 } // namespace OHOS
4610