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