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