• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hilog/log.h"
19 #include "image_napi_utils.h"
20 #include "image_pixel_map_napi.h"
21 #include "image_trace.h"
22 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
23 #include "color_space_object_convertor.h"
24 #include "js_runtime_utils.h"
25 #include "napi_message_sequence.h"
26 #endif
27 #include "hitrace_meter.h"
28 #include "pixel_map.h"
29 
30 using OHOS::HiviewDFX::HiLog;
31 namespace {
32     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "PixelMapNapi"};
33     constexpr uint32_t NUM_0 = 0;
34     constexpr uint32_t NUM_1 = 1;
35     constexpr uint32_t NUM_2 = 2;
36     constexpr uint32_t NUM_3 = 3;
37     constexpr uint32_t NUM_4 = 4;
38 }
39 
40 namespace OHOS {
41 namespace Media {
42 
43 static const std::string CLASS_NAME = "PixelMap";
44 thread_local napi_ref PixelMapNapi::sConstructor_ = nullptr;
45 std::shared_ptr<PixelMap> PixelMapNapi::sPixelMap_ = nullptr;
46 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
47 NAPI_MessageSequence* napi_messageSequence = nullptr;
48 #endif
49 
50 struct PositionArea {
51     void* pixels;
52     size_t size;
53     uint32_t offset;
54     uint32_t stride;
55     Rect region;
56 };
57 
58 struct PixelMapAsyncContext {
59     napi_env env;
60     napi_async_work work;
61     napi_deferred deferred;
62     napi_ref callbackRef;
63     uint32_t status;
64     PixelMapNapi *nConstructor;
65     void* colorsBuffer;
66     size_t colorsBufferSize;
67     InitializationOptions opts;
68     PositionArea area;
69     std::shared_ptr<PixelMap> rPixelMap;
70     std::shared_ptr<PixelMap> alphaMap;
71     double alpha = -1;
72     uint32_t resultUint32;
73     ImageInfo imageInfo;
74     double xArg = 0;
75     double yArg = 0;
76     bool xBarg = false;
77     bool yBarg = false;
78 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
79     std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace;
80 #endif
81 };
82 
ParsePixlForamt(int32_t val)83 static PixelFormat ParsePixlForamt(int32_t val)
84 {
85     if (val <= static_cast<int32_t>(PixelFormat::CMYK)) {
86         return PixelFormat(val);
87     }
88 
89     return PixelFormat::UNKNOWN;
90 }
91 
ParseAlphaType(int32_t val)92 static AlphaType ParseAlphaType(int32_t val)
93 {
94     if (val <= static_cast<int32_t>(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
95         return AlphaType(val);
96     }
97 
98     return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
99 
100 }
101 
ParseScaleMode(int32_t val)102 static ScaleMode ParseScaleMode(int32_t val)
103 {
104     if (val <= static_cast<int32_t>(ScaleMode::CENTER_CROP)) {
105         return ScaleMode(val);
106     }
107 
108     return ScaleMode::FIT_TARGET_SIZE;
109 }
110 
parseSize(napi_env env,napi_value root,Size * size)111 static bool parseSize(napi_env env, napi_value root, Size* size)
112 {
113     if (size == nullptr) {
114         return false;
115     }
116 
117     if (!GET_INT32_BY_NAME(root, "height", size->height)) {
118         return false;
119     }
120 
121     if (!GET_INT32_BY_NAME(root, "width", size->width)) {
122         return false;
123     }
124 
125     return true;
126 }
127 
parseInitializationOptions(napi_env env,napi_value root,InitializationOptions * opts)128 static bool parseInitializationOptions(napi_env env, napi_value root, InitializationOptions* opts)
129 {
130     uint32_t tmpNumber = 0;
131     napi_value tmpValue = nullptr;
132 
133     if (opts == nullptr) {
134         return false;
135     }
136 
137     if (!GET_BOOL_BY_NAME(root, "editable", opts->editable)) {
138         opts->editable = true;
139     }
140 
141     if (!GET_UINT32_BY_NAME(root, "alphaType", tmpNumber)) {
142         HiLog::Info(LABEL, "no alphaType in initialization options");
143     }
144     opts->alphaType = ParseAlphaType(tmpNumber);
145 
146     tmpNumber = 0;
147     if (!GET_UINT32_BY_NAME(root, "pixelFormat", tmpNumber)) {
148         HiLog::Info(LABEL, "no pixelFormat in initialization options");
149     }
150     opts->pixelFormat = ParsePixlForamt(tmpNumber);
151 
152     tmpNumber = 0;
153     if (!GET_UINT32_BY_NAME(root, "scaleMode", tmpNumber)) {
154         HiLog::Info(LABEL, "no scaleMode in initialization options");
155     }
156     opts->scaleMode = ParseScaleMode(tmpNumber);
157 
158     if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
159         return false;
160     }
161 
162     if (!parseSize(env, tmpValue, &(opts->size))) {
163         return false;
164     }
165     return true;
166 }
167 
parseRegion(napi_env env,napi_value root,Rect * region)168 static bool parseRegion(napi_env env, napi_value root, Rect* region)
169 {
170     napi_value tmpValue = nullptr;
171 
172     if (region == nullptr) {
173         return false;
174     }
175 
176     if (!GET_INT32_BY_NAME(root, "x", region->left)) {
177         return false;
178     }
179 
180     if (!GET_INT32_BY_NAME(root, "y", region->top)) {
181         return false;
182     }
183 
184     if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
185         return false;
186     }
187 
188     if (!GET_INT32_BY_NAME(tmpValue, "height", region->height)) {
189         return false;
190     }
191 
192     if (!GET_INT32_BY_NAME(tmpValue, "width", region->width)) {
193         return false;
194     }
195 
196     return true;
197 }
198 
parsePositionArea(napi_env env,napi_value root,PositionArea * area)199 static bool parsePositionArea(napi_env env, napi_value root, PositionArea* area)
200 {
201     napi_value tmpValue = nullptr;
202 
203     if (area == nullptr) {
204         return false;
205     }
206 
207     if (!GET_BUFFER_BY_NAME(root, "pixels", area->pixels, area->size)) {
208         return false;
209     }
210 
211     if (!GET_UINT32_BY_NAME(root, "offset", area->offset)) {
212         return false;
213     }
214 
215     if (!GET_UINT32_BY_NAME(root, "stride", area->stride)) {
216         return false;
217     }
218 
219     if (!GET_NODE_BY_NAME(root, "region", tmpValue)) {
220         return false;
221     }
222 
223     if (!parseRegion(env, tmpValue, &(area->region))) {
224         return false;
225     }
226     return true;
227 }
228 
CommonCallbackRoutine(napi_env env,PixelMapAsyncContext * & asyncContext,const napi_value & valueParam)229 static void CommonCallbackRoutine(napi_env env, PixelMapAsyncContext* &asyncContext, const napi_value &valueParam)
230 {
231     napi_value result[NUM_2] = {0};
232     napi_value retVal;
233     napi_value callback = nullptr;
234 
235     napi_get_undefined(env, &result[NUM_0]);
236     napi_get_undefined(env, &result[NUM_1]);
237 
238     napi_handle_scope scope = nullptr;
239     napi_open_handle_scope(env, &scope);
240     if (scope == nullptr) {
241         return;
242     }
243 
244     if (asyncContext == nullptr) {
245         return;
246     }
247     if (asyncContext->status == SUCCESS) {
248         result[NUM_1] = valueParam;
249     } else {
250         napi_create_uint32(env, asyncContext->status, &result[NUM_0]);
251     }
252 
253     if (asyncContext->deferred) {
254         if (asyncContext->status == SUCCESS) {
255             napi_resolve_deferred(env, asyncContext->deferred, result[NUM_1]);
256         } else {
257             napi_reject_deferred(env, asyncContext->deferred, result[NUM_0]);
258         }
259     } else {
260         napi_get_reference_value(env, asyncContext->callbackRef, &callback);
261         napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
262         napi_delete_reference(env, asyncContext->callbackRef);
263     }
264 
265     napi_delete_async_work(env, asyncContext->work);
266     napi_close_handle_scope(env, scope);
267 
268     delete asyncContext;
269     asyncContext = nullptr;
270 }
271 
STATIC_COMPLETE_FUNC(EmptyResult)272 STATIC_COMPLETE_FUNC(EmptyResult)
273 {
274     napi_value result = nullptr;
275     napi_get_undefined(env, &result);
276 
277     auto context = static_cast<PixelMapAsyncContext*>(data);
278 
279     CommonCallbackRoutine(env, context, result);
280 }
281 
PixelMapNapi()282 PixelMapNapi::PixelMapNapi():env_(nullptr)
283 {
284 
285 }
286 
~PixelMapNapi()287 PixelMapNapi::~PixelMapNapi()
288 {
289     release();
290 }
291 
DoInitAfter(napi_env env,napi_value exports,napi_value constructor,size_t property_count,const napi_property_descriptor * properties)292 static napi_value DoInitAfter(napi_env env,
293                               napi_value exports,
294                               napi_value constructor,
295                               size_t property_count,
296                               const napi_property_descriptor* properties)
297 {
298     napi_value global = nullptr;
299     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
300         napi_get_global(env, &global)),
301         nullptr, HiLog::Error(LABEL, "Init:get global fail")
302     );
303 
304     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
305         napi_set_named_property(env, global, CLASS_NAME.c_str(), constructor)),
306         nullptr, HiLog::Error(LABEL, "Init:set global named property fail")
307     );
308 
309     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
310         napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor)),
311         nullptr, HiLog::Error(LABEL, "set named property fail")
312     );
313 
314     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
315         napi_define_properties(env, exports, property_count, properties)),
316         nullptr, HiLog::Error(LABEL, "define properties fail")
317     );
318     return exports;
319 }
320 
Init(napi_env env,napi_value exports)321 napi_value PixelMapNapi::Init(napi_env env, napi_value exports)
322 {
323     napi_property_descriptor props[] = {
324         DECLARE_NAPI_FUNCTION("readPixelsToBuffer", ReadPixelsToBuffer),
325         DECLARE_NAPI_FUNCTION("readPixels", ReadPixels),
326         DECLARE_NAPI_FUNCTION("writePixels", WritePixels),
327         DECLARE_NAPI_FUNCTION("writeBufferToPixels", WriteBufferToPixels),
328         DECLARE_NAPI_FUNCTION("getImageInfo", GetImageInfo),
329         DECLARE_NAPI_FUNCTION("getBytesNumberPerRow", GetBytesNumberPerRow),
330         DECLARE_NAPI_FUNCTION("getPixelBytesNumber", GetPixelBytesNumber),
331         DECLARE_NAPI_FUNCTION("isSupportAlpha", IsSupportAlpha),
332         DECLARE_NAPI_FUNCTION("setAlphaAble", SetAlphaAble),
333         DECLARE_NAPI_FUNCTION("createAlphaPixelmap", CreateAlphaPixelmap),
334         DECLARE_NAPI_FUNCTION("getDensity", GetDensity),
335         DECLARE_NAPI_FUNCTION("setDensity", SetDensity),
336         DECLARE_NAPI_FUNCTION("opacity", SetAlpha),
337         DECLARE_NAPI_FUNCTION("release", Release),
338         DECLARE_NAPI_FUNCTION("scale", Scale),
339         DECLARE_NAPI_FUNCTION("translate", Translate),
340         DECLARE_NAPI_FUNCTION("rotate", Rotate),
341         DECLARE_NAPI_FUNCTION("flip", Flip),
342         DECLARE_NAPI_FUNCTION("crop", Crop),
343         DECLARE_NAPI_FUNCTION("getColorSpace", GetColorSpace),
344         DECLARE_NAPI_FUNCTION("setColorSpace", SetColorSpace),
345         DECLARE_NAPI_FUNCTION("marshalling", Marshalling),
346         DECLARE_NAPI_FUNCTION("unmarshalling", Unmarshalling),
347         DECLARE_NAPI_GETTER("isEditable", GetIsEditable),
348     };
349 
350     napi_property_descriptor static_prop[] = {
351         DECLARE_NAPI_STATIC_FUNCTION("createPixelMap", CreatePixelMap),
352         DECLARE_NAPI_STATIC_FUNCTION("unmarshalling", Unmarshalling),
353     };
354 
355     napi_value constructor = nullptr;
356 
357     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
358         napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
359                           Constructor, nullptr, IMG_ARRAY_SIZE(props),
360                           props, &constructor)),
361         nullptr, HiLog::Error(LABEL, "define class fail")
362     );
363 
364     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
365         napi_create_reference(env, constructor, 1, &sConstructor_)),
366         nullptr, HiLog::Error(LABEL, "create reference fail")
367     );
368 
369     auto result = DoInitAfter(env, exports, constructor,
370         IMG_ARRAY_SIZE(static_prop), static_prop);
371 
372     HiLog::Debug(LABEL, "Init success");
373     return result;
374 }
375 
GetPixelMap(napi_env env,napi_value pixelmap)376 std::shared_ptr<PixelMap> PixelMapNapi::GetPixelMap(napi_env env, napi_value pixelmap)
377 {
378     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
379 
380     napi_status status = napi_unwrap(env, pixelmap, reinterpret_cast<void**>(&pixelMapNapi));
381     if (!IMG_IS_OK(status)) {
382         HiLog::Error(LABEL, "GetPixelMap napi unwrap failed");
383         return nullptr;
384     }
385 
386     if (pixelMapNapi == nullptr) {
387         HiLog::Error(LABEL, "GetPixelMap pixmapNapi is nullptr");
388         return nullptr;
389     }
390 
391     auto pixelmapNapiPtr = pixelMapNapi.release();
392     if (pixelmapNapiPtr == nullptr) {
393         HiLog::Error(LABEL, "GetPixelMap pixelmapNapi is nullptr");
394         return nullptr;
395     }
396     return pixelmapNapiPtr->nativePixelMap_;
397 }
398 
GetPixelMap()399 std::shared_ptr<PixelMap>* PixelMapNapi::GetPixelMap()
400 {
401     return &nativePixelMap_;
402 }
403 
IsLockPixelMap()404 bool PixelMapNapi::IsLockPixelMap()
405 {
406     return (lockCount > 0);
407 }
408 
LockPixelMap()409 bool PixelMapNapi::LockPixelMap()
410 {
411     lockCount++;
412     return true;
413 }
414 
UnlockPixelMap()415 void PixelMapNapi::UnlockPixelMap()
416 {
417     if (lockCount > 0) {
418         lockCount--;
419     }
420 }
421 
OHOS_MEDIA_GetPixelMap(napi_env env,napi_value value)422 extern "C" __attribute__((visibility("default"))) void* OHOS_MEDIA_GetPixelMap(napi_env env, napi_value value)
423 {
424     PixelMapNapi *pixmapNapi = nullptr;
425     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
426     if (pixmapNapi == nullptr) {
427         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
428         return nullptr;
429     }
430     return reinterpret_cast<void*>(pixmapNapi->GetPixelMap());
431 }
432 
OHOS_MEDIA_GetImageInfo(napi_env env,napi_value value,OhosPixelMapInfo * info)433 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_GetImageInfo(napi_env env, napi_value value,
434     OhosPixelMapInfo *info)
435 {
436     HiLog::Debug(LABEL, "GetImageInfo IN");
437 
438     if (info == nullptr) {
439         HiLog::Error(LABEL, "info is nullptr");
440         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
441     }
442 
443     PixelMapNapi *pixmapNapi = nullptr;
444     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
445     if (pixmapNapi == nullptr) {
446         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
447         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
448     }
449 
450     std::shared_ptr<PixelMap> *pixelMap = pixmapNapi->GetPixelMap();
451     if ((pixelMap == nullptr) || ((*pixelMap) == nullptr)) {
452         HiLog::Error(LABEL, "pixelMap is nullptr");
453         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
454     }
455 
456     ImageInfo imageInfo;
457     (*pixelMap)->GetImageInfo(imageInfo);
458     info->width = imageInfo.size.width;
459     info->height = imageInfo.size.height;
460     info->rowSize = (*pixelMap)->GetRowBytes();
461     info->pixelFormat = static_cast<int32_t>(imageInfo.pixelFormat);
462 
463     HiLog::Debug(LABEL, "GetImageInfo, w=%{public}u, h=%{public}u, r=%{public}u, f=%{public}d",
464         info->width, info->height, info->rowSize, info->pixelFormat);
465 
466     return OHOS_IMAGE_RESULT_SUCCESS;
467 }
468 
OHOS_MEDIA_AccessPixels(napi_env env,napi_value value,uint8_t ** addrPtr)469 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_AccessPixels(napi_env env, napi_value value,
470     uint8_t** addrPtr)
471 {
472     HiLog::Debug(LABEL, "AccessPixels IN");
473 
474     PixelMapNapi *pixmapNapi = nullptr;
475     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
476     if (pixmapNapi == nullptr) {
477         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
478         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
479     }
480 
481     std::shared_ptr<PixelMap> *pixelMap = pixmapNapi->GetPixelMap();
482     if ((pixelMap == nullptr) || ((*pixelMap) == nullptr)) {
483         HiLog::Error(LABEL, "pixelMap is nullptr");
484         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
485     }
486 
487     const uint8_t *constPixels = (*pixelMap)->GetPixels();
488     if (constPixels == nullptr) {
489         HiLog::Error(LABEL, "const pixels is nullptr");
490         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
491     }
492 
493     uint8_t *pixels = const_cast<uint8_t*>(constPixels);
494     if (pixels == nullptr) {
495         HiLog::Error(LABEL, "pixels is nullptr");
496         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
497     }
498 
499     pixmapNapi->LockPixelMap();
500 
501     if (addrPtr != nullptr) {
502         *addrPtr = pixels;
503     }
504 
505     HiLog::Debug(LABEL, "AccessPixels OUT");
506     return OHOS_IMAGE_RESULT_SUCCESS;
507 }
508 
OHOS_MEDIA_UnAccessPixels(napi_env env,napi_value value)509 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_UnAccessPixels(napi_env env, napi_value value)
510 {
511     HiLog::Debug(LABEL, "UnAccessPixels IN");
512 
513     PixelMapNapi *pixmapNapi = nullptr;
514     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
515     if (pixmapNapi == nullptr) {
516         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
517         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
518     }
519 
520     pixmapNapi->UnlockPixelMap();
521 
522     return OHOS_IMAGE_RESULT_SUCCESS;
523 }
524 
Constructor(napi_env env,napi_callback_info info)525 napi_value PixelMapNapi::Constructor(napi_env env, napi_callback_info info)
526 {
527     napi_value undefineVar = nullptr;
528     napi_get_undefined(env, &undefineVar);
529 
530     napi_status status;
531     napi_value thisVar = nullptr;
532     napi_get_undefined(env, &thisVar);
533 
534     HiLog::Debug(LABEL, "Constructor IN");
535     IMG_JS_NO_ARGS(env, info, status, thisVar);
536 
537     IMG_NAPI_CHECK_RET(IMG_IS_READY(status, thisVar), undefineVar);
538     std::unique_ptr<PixelMapNapi> pPixelMapNapi = std::make_unique<PixelMapNapi>();
539 
540     IMG_NAPI_CHECK_RET(IMG_NOT_NULL(pPixelMapNapi), undefineVar);
541 
542     pPixelMapNapi->env_ = env;
543     pPixelMapNapi->nativePixelMap_ = sPixelMap_;
544     pPixelMapNapi->nativeInner_ = sPixelMap_;
545 
546     status = napi_wrap(env, thisVar, reinterpret_cast<void*>(pPixelMapNapi.get()),
547         PixelMapNapi::Destructor, nullptr, nullptr);
548     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), undefineVar, HiLog::Error(LABEL, "Failure wrapping js to native napi"));
549 
550     pPixelMapNapi.release();
551     sPixelMap_ = nullptr;
552 
553     return thisVar;
554 }
555 
Destructor(napi_env env,void * nativeObject,void * finalize)556 void PixelMapNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
557 {
558     if (nativeObject != nullptr) {
559         delete reinterpret_cast<PixelMapNapi*>(nativeObject);
560         nativeObject = nullptr;
561     }
562 }
563 
STATIC_EXEC_FUNC(CreatePixelMap)564 STATIC_EXEC_FUNC(CreatePixelMap)
565 {
566     auto context = static_cast<PixelMapAsyncContext*>(data);
567     auto colors = static_cast<uint32_t*>(context->colorsBuffer);
568     auto pixelmap = PixelMap::Create(colors, context->colorsBufferSize, context->opts);
569 
570     context->rPixelMap = std::move(pixelmap);
571 
572     if (IMG_NOT_NULL(context->rPixelMap)) {
573         context->status = SUCCESS;
574     } else {
575         context->status = ERROR;
576     }
577 }
578 
CreatePixelMapComplete(napi_env env,napi_status status,void * data)579 void PixelMapNapi::CreatePixelMapComplete(napi_env env, napi_status status, void *data)
580 {
581     napi_value constructor = nullptr;
582     napi_value result = nullptr;
583 
584     HiLog::Debug(LABEL, "CreatePixelMapComplete IN");
585     auto context = static_cast<PixelMapAsyncContext*>(data);
586 
587     status = napi_get_reference_value(env, sConstructor_, &constructor);
588 
589     if (IMG_IS_OK(status)) {
590         sPixelMap_ = context->rPixelMap;
591         status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
592     }
593 
594     if (!IMG_IS_OK(status)) {
595         context->status = ERROR;
596         HiLog::Error(LABEL, "New instance could not be obtained");
597         napi_get_undefined(env, &result);
598     }
599 
600     CommonCallbackRoutine(env, context, result);
601 }
602 
CreatePixelMap(napi_env env,napi_callback_info info)603 napi_value PixelMapNapi::CreatePixelMap(napi_env env, napi_callback_info info)
604 {
605     napi_value globalValue;
606     napi_get_global(env, &globalValue);
607     napi_value func;
608     napi_get_named_property(env, globalValue, "requireNapi", &func);
609 
610     napi_value imageInfo;
611     napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
612     napi_value funcArgv[1] = { imageInfo };
613     napi_value returnValue;
614     napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
615 
616     napi_value result = nullptr;
617     napi_get_undefined(env, &result);
618 
619     int32_t refCount = 1;
620 
621     napi_status status;
622     napi_value thisVar = nullptr;
623     napi_value argValue[NUM_4] = {0};
624     size_t argCount = NUM_4;
625     HiLog::Debug(LABEL, "CreatePixelMap IN");
626 
627     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
628 
629     // we are static method!
630     // thisVar is nullptr here
631     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
632     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
633 
634     status = napi_get_arraybuffer_info(env, argValue[NUM_0], &(asyncContext->colorsBuffer),
635         &(asyncContext->colorsBufferSize));
636 
637     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "colors mismatch"));
638 
639     IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[1], &(asyncContext->opts)),
640         nullptr, HiLog::Error(LABEL, "InitializationOptions mismatch"));
641 
642     if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
643         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
644     }
645 
646     if (asyncContext->callbackRef == nullptr) {
647         napi_create_promise(env, &(asyncContext->deferred), &result);
648     } else {
649         napi_get_undefined(env, &result);
650     }
651 
652     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMap",
653         CreatePixelMapExec, CreatePixelMapComplete, asyncContext, asyncContext->work);
654 
655     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
656         nullptr, HiLog::Error(LABEL, "fail to create async work"));
657     return result;
658 }
659 
CreatePixelMap(napi_env env,std::shared_ptr<PixelMap> pixelmap)660 napi_value PixelMapNapi::CreatePixelMap(napi_env env, std::shared_ptr<PixelMap> pixelmap)
661 {
662     napi_value globalValue;
663     napi_get_global(env, &globalValue);
664     napi_value func;
665     napi_get_named_property(env, globalValue, "requireNapi", &func);
666 
667     napi_value imageInfo;
668     napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
669     napi_value funcArgv[1] = { imageInfo };
670     napi_value returnValue;
671     napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
672 
673     napi_value constructor = nullptr;
674     napi_value result = nullptr;
675     napi_status status;
676 
677     HiLog::Debug(LABEL, "CreatePixelMap IN");
678     status = napi_get_reference_value(env, sConstructor_, &constructor);
679 
680     if (IMG_IS_OK(status)) {
681         sPixelMap_ = pixelmap;
682         status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
683     }
684 
685     if (!IMG_IS_OK(status)) {
686         HiLog::Error(LABEL, "CreatePixelMap | New instance could not be obtained");
687         napi_get_undefined(env, &result);
688     }
689 
690     return result;
691 }
692 
STATIC_EXEC_FUNC(Unmarshalling)693 STATIC_EXEC_FUNC(Unmarshalling)
694 {
695 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
696     auto context = static_cast<PixelMapAsyncContext*>(data);
697 
698     auto messageParcel = napi_messageSequence->GetMessageParcel();
699     auto pixelmap = PixelMap::Unmarshalling(*messageParcel);
700     std::unique_ptr<OHOS::Media::PixelMap> pixelmap_ptr(pixelmap);
701 
702     context->rPixelMap = std::move(pixelmap_ptr);
703 
704     if (IMG_NOT_NULL(context->rPixelMap)) {
705         context->status = SUCCESS;
706     } else {
707         context->status = ERROR;
708     }
709 #endif
710 }
711 
UnmarshallingComplete(napi_env env,napi_status status,void * data)712 void PixelMapNapi::UnmarshallingComplete(napi_env env, napi_status status, void *data)
713 {
714     napi_value constructor = nullptr;
715     napi_value result = nullptr;
716 
717     HiLog::Debug(LABEL, "UnmarshallingComplete IN");
718     auto context = static_cast<PixelMapAsyncContext*>(data);
719 
720     status = napi_get_reference_value(env, sConstructor_, &constructor);
721     if (IMG_IS_OK(status)) {
722         sPixelMap_ = context->rPixelMap;
723         status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
724     }
725 
726     if (!IMG_IS_OK(status)) {
727         context->status = ERROR;
728         HiLog::Error(LABEL, "New instance could not be obtained");
729         napi_get_undefined(env, &result);
730     }
731 
732     CommonCallbackRoutine(env, context, result);
733 }
734 
Unmarshalling(napi_env env,napi_callback_info info)735 napi_value PixelMapNapi::Unmarshalling(napi_env env, napi_callback_info info)
736 {
737 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
738     napi_value globalValue;
739     napi_get_global(env, &globalValue);
740     napi_value func;
741     napi_get_named_property(env, globalValue, "requireNapi", &func);
742 
743     napi_value imageInfo;
744     napi_create_string_utf8(env, "multimedia.image", NAPI_AUTO_LENGTH, &imageInfo);
745     napi_value funcArgv[1] = { imageInfo };
746     napi_value returnValue;
747     napi_call_function(env, globalValue, func, 1, funcArgv, &returnValue);
748     napi_value result = nullptr;
749     napi_get_undefined(env, &result);
750 
751     int32_t refCount = 1;
752 
753     napi_status status;
754     napi_value thisVar = nullptr;
755     napi_value argValue[NUM_4] = {0};
756     size_t argCount = NUM_4;
757     HiLog::Debug(LABEL, "Unmarshalling IN");
758 
759     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
760 
761     // we are static method!
762     // thisVar is nullptr here
763     if (!IMG_IS_OK(status)) {
764         return ImageNapiUtils::ThrowExceptionError(
765             env, ERR_IMAGE_INVALID_PARAMETER, "Fail to napi_get_cb_info");
766     }
767     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
768 
769     if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
770         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
771     }
772 
773     napi_unwrap(env, argValue[NUM_0], (void **)&napi_messageSequence);
774 
775     if (asyncContext->callbackRef == nullptr) {
776         napi_create_promise(env, &(asyncContext->deferred), &result);
777     } else {
778         napi_get_undefined(env, &result);
779     }
780 
781     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "Unmarshalling",
782         UnmarshallingExec, UnmarshallingComplete, asyncContext, asyncContext->work);
783 
784     if (!IMG_IS_OK(status)) {
785         return ImageNapiUtils::ThrowExceptionError(
786             env, ERROR, "Fail to create async work");
787     }
788     return result;
789 #else
790     napi_value result = nullptr;
791     return result;
792 #endif
793 }
794 
GetIsEditable(napi_env env,napi_callback_info info)795 napi_value PixelMapNapi::GetIsEditable(napi_env env, napi_callback_info info)
796 {
797     napi_value result = nullptr;
798     napi_get_undefined(env, &result);
799 
800     napi_status status;
801     napi_value thisVar = nullptr;
802     size_t argCount = 0;
803     HiLog::Debug(LABEL, "GetIsEditable IN");
804 
805     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
806 
807     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
808 
809     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
810     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
811 
812     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
813 
814     if (pixelMapNapi->nativePixelMap_ == nullptr) {
815         return result;
816     }
817     bool isEditable = pixelMapNapi->nativePixelMap_->IsEditable();
818 
819     napi_get_boolean(env, isEditable, &result);
820     pixelMapNapi.release();
821 
822     return result;
823 }
824 
ReadPixelsToBuffer(napi_env env,napi_callback_info info)825 napi_value PixelMapNapi::ReadPixelsToBuffer(napi_env env, napi_callback_info info)
826 {
827     StartTrace(HITRACE_TAG_ZIMAGE, "ReadPixelsToBuffer");
828     napi_value result = nullptr;
829     napi_get_undefined(env, &result);
830 
831     int32_t refCount = 1;
832     napi_status status;
833     napi_value thisVar = nullptr;
834     napi_value argValue[NUM_2] = {0};
835     size_t argCount = NUM_2;
836 
837     HiLog::Debug(LABEL, "ReadPixelsToBuffer IN");
838     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
839 
840     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
841 
842     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
843     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
844 
845     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
846         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
847 
848     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
849 
850     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
851         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
852 
853     status = napi_get_arraybuffer_info(env, argValue[NUM_0],
854             &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
855 
856     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "colors mismatch"));
857 
858     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
859         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
860     }
861 
862     if (asyncContext->callbackRef == nullptr) {
863         napi_create_promise(env, &(asyncContext->deferred), &result);
864     } else {
865         napi_get_undefined(env, &result);
866     }
867 
868     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsToBuffer",
869         [](napi_env env, void *data)
870         {
871             auto context = static_cast<PixelMapAsyncContext*>(data);
872             context->status = context->rPixelMap->ReadPixels(
873                 context->colorsBufferSize, static_cast<uint8_t*>(context->colorsBuffer));
874         }
875         , EmptyResultComplete, asyncContext, asyncContext->work);
876 
877     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
878         nullptr, HiLog::Error(LABEL, "fail to create async work"));
879     FinishTrace(HITRACE_TAG_ZIMAGE);
880     return result;
881 }
882 
ReadPixels(napi_env env,napi_callback_info info)883 napi_value PixelMapNapi::ReadPixels(napi_env env, napi_callback_info info)
884 {
885     napi_value result = nullptr;
886     napi_get_undefined(env, &result);
887 
888     int32_t refCount = 1;
889     napi_status status;
890     napi_value thisVar = nullptr;
891     napi_value argValue[NUM_2] = {0};
892     size_t argCount = NUM_2;
893 
894     HiLog::Debug(LABEL, "ReadPixels IN");
895     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
896 
897     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
898 
899     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
900     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
901 
902     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
903         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
904 
905     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
906 
907     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
908         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
909 
910     IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
911         nullptr, HiLog::Error(LABEL, "fail to parse position area"));
912 
913     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
914         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
915     }
916 
917     if (asyncContext->callbackRef == nullptr) {
918         napi_create_promise(env, &(asyncContext->deferred), &result);
919     } else {
920         napi_get_undefined(env, &result);
921     }
922 
923     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixels",
924         [](napi_env env, void *data)
925         {
926             auto context = static_cast<PixelMapAsyncContext*>(data);
927             auto area = context->area;
928             context->status = context->rPixelMap->ReadPixels(
929                 area.size, area.offset, area.stride, area.region, static_cast<uint8_t*>(area.pixels));
930         }, EmptyResultComplete, asyncContext, asyncContext->work);
931 
932     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
933         nullptr, HiLog::Error(LABEL, "fail to create async work"));
934     return result;
935 }
936 
WritePixels(napi_env env,napi_callback_info info)937 napi_value PixelMapNapi::WritePixels(napi_env env, napi_callback_info info)
938 {
939     napi_value result = nullptr;
940     napi_get_undefined(env, &result);
941 
942     int32_t refCount = 1;
943     napi_status status;
944     napi_value thisVar = nullptr;
945     napi_value argValue[NUM_2] = {0};
946     size_t argCount = NUM_2;
947 
948     HiLog::Debug(LABEL, "WritePixels IN");
949     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
950 
951     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
952 
953     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
954     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
955 
956     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
957         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
958 
959     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
960 
961     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
962         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
963 
964     IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
965         nullptr, HiLog::Error(LABEL, "fail to parse position area"));
966 
967     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
968         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
969     }
970 
971     if (asyncContext->callbackRef == nullptr) {
972         napi_create_promise(env, &(asyncContext->deferred), &result);
973     } else {
974         napi_get_undefined(env, &result);
975     }
976 
977     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WritePixels",
978         [](napi_env env, void *data)
979         {
980             auto context = static_cast<PixelMapAsyncContext*>(data);
981             auto area = context->area;
982             context->status = context->rPixelMap->WritePixels(
983                 static_cast<uint8_t*>(area.pixels), area.size, area.offset, area.stride, area.region);
984         }, EmptyResultComplete, asyncContext, asyncContext->work);
985 
986     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
987         nullptr, HiLog::Error(LABEL, "fail to create async work"));
988     return result;
989 
990 }
991 
WriteBufferToPixels(napi_env env,napi_callback_info info)992 napi_value PixelMapNapi::WriteBufferToPixels(napi_env env, napi_callback_info info)
993 {
994     StartTrace(HITRACE_TAG_ZIMAGE, "WriteBufferToPixels");
995     napi_value result = nullptr;
996     napi_get_undefined(env, &result);
997 
998     int32_t refCount = 1;
999     napi_status status;
1000     napi_value thisVar = nullptr;
1001     napi_value argValue[NUM_2] = {0};
1002     size_t argCount = NUM_2;
1003 
1004     HiLog::Debug(LABEL, "WriteBufferToPixels IN");
1005     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1006 
1007     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1008 
1009     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1010     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1011 
1012     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1013         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
1014 
1015     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1016 
1017     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1018         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
1019     status = napi_get_arraybuffer_info(env, argValue[NUM_0],
1020         &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
1021 
1022     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1023         nullptr, HiLog::Error(LABEL, "fail to get buffer info"));
1024 
1025     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1026         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1027     }
1028 
1029     if (asyncContext->callbackRef == nullptr) {
1030         napi_create_promise(env, &(asyncContext->deferred), &result);
1031     } else {
1032         napi_get_undefined(env, &result);
1033     }
1034 
1035     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WriteBufferToPixels",
1036         [](napi_env env, void *data)
1037         {
1038             auto context = static_cast<PixelMapAsyncContext*>(data);
1039             context->status = context->rPixelMap->WritePixels(static_cast<uint8_t*>(context->colorsBuffer),
1040                 context->colorsBufferSize);
1041         }, EmptyResultComplete, asyncContext, asyncContext->work);
1042 
1043     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1044         nullptr, HiLog::Error(LABEL, "fail to create async work"));
1045     FinishTrace(HITRACE_TAG_ZIMAGE);
1046     return result;
1047 }
1048 
STATIC_COMPLETE_FUNC(GetImageInfo)1049 STATIC_COMPLETE_FUNC(GetImageInfo)
1050 {
1051     HiLog::Debug(LABEL, "[PixelMap]GetImageInfoComplete IN");
1052     napi_value result = nullptr;
1053     napi_create_object(env, &result);
1054     auto context = static_cast<PixelMapAsyncContext*>(data);
1055     napi_value size = nullptr;
1056     napi_create_object(env, &size);
1057     napi_value sizeWith = nullptr;
1058     napi_create_int32(env, context->imageInfo.size.width, &sizeWith);
1059     napi_set_named_property(env, size, "width", sizeWith);
1060     napi_value sizeHeight = nullptr;
1061     napi_create_int32(env, context->imageInfo.size.height, &sizeHeight);
1062     napi_set_named_property(env, size, "height", sizeHeight);
1063     napi_set_named_property(env, result, "size", size);
1064     napi_value pixelFormatValue = nullptr;
1065     napi_create_int32(env, static_cast<int32_t>(context->imageInfo.pixelFormat), &pixelFormatValue);
1066     napi_set_named_property(env, result, "pixelFormat", pixelFormatValue);
1067     napi_value colorSpaceValue = nullptr;
1068     napi_create_int32(env, static_cast<int32_t>(context->imageInfo.colorSpace), &colorSpaceValue);
1069     napi_set_named_property(env, result, "colorSpace", colorSpaceValue);
1070     napi_value alphaTypeValue = nullptr;
1071     napi_create_int32(env, static_cast<int32_t>(context->imageInfo.alphaType), &alphaTypeValue);
1072     napi_set_named_property(env, result, "alphaType", alphaTypeValue);
1073     napi_value densityValue = nullptr;
1074     napi_create_int32(env, static_cast<int32_t>(context->imageInfo.baseDensity), &densityValue);
1075     napi_set_named_property(env, result, "density", densityValue);
1076     if (!IMG_IS_OK(status)) {
1077         context->status = ERROR;
1078         HiLog::Error(LABEL, "napi_create_int32 failed!");
1079         napi_get_undefined(env, &result);
1080     } else {
1081         context->status = SUCCESS;
1082     }
1083     HiLog::Debug(LABEL, "[PixelMap]GetImageInfoComplete OUT");
1084     CommonCallbackRoutine(env, context, result);
1085 }
GetImageInfo(napi_env env,napi_callback_info info)1086 napi_value PixelMapNapi::GetImageInfo(napi_env env, napi_callback_info info)
1087 {
1088     napi_value result = nullptr;
1089     napi_get_undefined(env, &result);
1090     int32_t refCount = 1;
1091     napi_status status;
1092     napi_value thisVar = nullptr;
1093     napi_value argValue[NUM_1] = {0};
1094     size_t argCount = 1;
1095     HiLog::Debug(LABEL, "GetImageInfo IN");
1096     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1097     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1098     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1099     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1100     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1101         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
1102     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1103     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1104         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
1105     if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1106         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1107     }
1108     if (asyncContext->callbackRef == nullptr) {
1109         napi_create_promise(env, &(asyncContext->deferred), &result);
1110     } else {
1111         napi_get_undefined(env, &result);
1112     }
1113     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfo",
1114         [](napi_env env, void *data)
1115         {
1116             auto context = static_cast<PixelMapAsyncContext*>(data);
1117             context->rPixelMap->GetImageInfo(context->imageInfo);
1118             context->status = SUCCESS;
1119         }, GetImageInfoComplete, asyncContext, asyncContext->work);
1120     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1121         nullptr, HiLog::Error(LABEL, "fail to create async work"));
1122     return result;
1123 }
1124 
GetBytesNumberPerRow(napi_env env,napi_callback_info info)1125 napi_value PixelMapNapi::GetBytesNumberPerRow(napi_env env, napi_callback_info info)
1126 {
1127     StartTrace(HITRACE_TAG_ZIMAGE, "GetBytesNumberPerRow");
1128     napi_value result = nullptr;
1129     napi_get_undefined(env, &result);
1130 
1131     napi_status status;
1132     napi_value thisVar = nullptr;
1133     size_t argCount = 0;
1134 
1135     HiLog::Debug(LABEL, "GetBytesNumberPerRow IN");
1136     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1137 
1138     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1139 
1140     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1141     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1142 
1143     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
1144     if (pixelMapNapi->nativePixelMap_ != nullptr) {
1145         uint32_t rowBytes = pixelMapNapi->nativePixelMap_->GetRowBytes();
1146         status = napi_create_int32(env, rowBytes, &result);
1147         if (!IMG_IS_OK(status)) {
1148             HiLog::Error(LABEL, "napi_create_int32 failed!");
1149         }
1150     } else {
1151         HiLog::Error(LABEL, "native pixelmap is nullptr!");
1152     }
1153     pixelMapNapi.release();
1154     FinishTrace(HITRACE_TAG_ZIMAGE);
1155     return result;
1156 }
1157 
GetPixelBytesNumber(napi_env env,napi_callback_info info)1158 napi_value PixelMapNapi::GetPixelBytesNumber(napi_env env, napi_callback_info info)
1159 {
1160     StartTrace(HITRACE_TAG_ZIMAGE, "GetPixelBytesNumber");
1161     napi_value result = nullptr;
1162     napi_get_undefined(env, &result);
1163 
1164     napi_status status;
1165     napi_value thisVar = nullptr;
1166     size_t argCount = 0;
1167 
1168     HiLog::Debug(LABEL, "GetPixelBytesNumber IN");
1169     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1170 
1171     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1172 
1173     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1174     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1175 
1176     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
1177     if (pixelMapNapi->nativePixelMap_ != nullptr) {
1178         uint32_t byteCount = pixelMapNapi->nativePixelMap_->GetByteCount();
1179         status = napi_create_int32(env, byteCount, &result);
1180         if (!IMG_IS_OK(status)) {
1181             HiLog::Error(LABEL, "napi_create_int32 failed!");
1182         }
1183     } else {
1184         HiLog::Error(LABEL, "native pixelmap is nullptr!");
1185     }
1186     pixelMapNapi.release();
1187     FinishTrace(HITRACE_TAG_ZIMAGE);
1188     return result;
1189 }
1190 
IsSupportAlpha(napi_env env,napi_callback_info info)1191 napi_value PixelMapNapi::IsSupportAlpha(napi_env env, napi_callback_info info)
1192 {
1193     napi_value result = nullptr;
1194     napi_get_undefined(env, &result);
1195 
1196     napi_status status;
1197     napi_value thisVar = nullptr;
1198     size_t argCount = NUM_0;
1199 
1200     HiLog::Debug(LABEL, "IsSupportAlpha IN");
1201     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1202 
1203     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1204 
1205     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1206     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1207 
1208     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
1209     if (pixelMapNapi->nativePixelMap_ != nullptr) {
1210         AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
1211         bool isSupportAlpha = !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
1212         status = napi_get_boolean(env, isSupportAlpha, &result);
1213         if (!IMG_IS_OK(status)) {
1214             HiLog::Error(LABEL, "napi_create_bool failed!");
1215         }
1216     } else {
1217         HiLog::Error(LABEL, "native pixelmap is nullptr!");
1218     }
1219     pixelMapNapi.release();
1220     return result;
1221 }
1222 
SetAlphaAble(napi_env env,napi_callback_info info)1223 napi_value PixelMapNapi::SetAlphaAble(napi_env env, napi_callback_info info)
1224 {
1225     napi_value result = nullptr;
1226     napi_get_undefined(env, &result);
1227 
1228     napi_status status;
1229     napi_value thisVar = nullptr;
1230     napi_value argValue[NUM_1] = {0};
1231     size_t argCount = NUM_1;
1232     bool isAlphaAble = false;
1233 
1234     HiLog::Debug(LABEL, "SetAlphaAble IN");
1235     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1236 
1237     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1238     NAPI_ASSERT(env, argCount > NUM_0, "Invalid input");
1239     NAPI_ASSERT(env, ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_boolean, "Invalid input type");
1240     NAPI_ASSERT(env, napi_get_value_bool(env, argValue[NUM_0], &isAlphaAble) == napi_ok, "Parse input error");
1241 
1242     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1243     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1244 
1245     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
1246 
1247     if (pixelMapNapi->nativePixelMap_ != nullptr) {
1248         AlphaType alphaType = pixelMapNapi->nativePixelMap_->GetAlphaType();
1249         if (isAlphaAble && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1250             pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
1251         } else if ((!isAlphaAble) && !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1252             pixelMapNapi->nativePixelMap_->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
1253         }
1254     } else {
1255         HiLog::Error(LABEL, "native pixelmap is nullptr!");
1256     }
1257     pixelMapNapi.release();
1258     return result;
1259 }
1260 
CreateAlphaPixelmapComplete(napi_env env,napi_status status,void * data)1261 static void CreateAlphaPixelmapComplete(napi_env env, napi_status status, void *data)
1262 {
1263     napi_value result = nullptr;
1264     napi_get_undefined(env, &result);
1265     auto context = static_cast<PixelMapAsyncContext*>(data);
1266 
1267     if (context->alphaMap != nullptr) {
1268         result = PixelMapNapi::CreatePixelMap(env, context->alphaMap);
1269         context->status = SUCCESS;
1270     } else {
1271         context->status = ERROR;
1272     }
1273     CommonCallbackRoutine(env, context, result);
1274 }
1275 
CreateAlphaPixelmap(napi_env env,napi_callback_info info)1276 napi_value PixelMapNapi::CreateAlphaPixelmap(napi_env env, napi_callback_info info)
1277 {
1278     napi_value result = nullptr;
1279     napi_get_undefined(env, &result);
1280     int32_t refCount = 1;
1281     napi_status status;
1282     napi_value thisVar = nullptr;
1283     napi_value argValue[NUM_1] = {0};
1284     size_t argCount = 1;
1285     HiLog::Debug(LABEL, "CreateAlphaPixelmap IN");
1286     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1287     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1288     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1289     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1290     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1291         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
1292     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
1293     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
1294         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
1295     if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1296         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1297     }
1298     if (asyncContext->callbackRef == nullptr) {
1299         napi_create_promise(env, &(asyncContext->deferred), &result);
1300     } else {
1301         napi_get_undefined(env, &result);
1302     }
1303     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreateAlphaPixelmap",
1304         [](napi_env env, void *data)
1305         {
1306             auto context = static_cast<PixelMapAsyncContext*>(data);
1307             InitializationOptions opts;
1308             opts.pixelFormat = PixelFormat::ALPHA_8;
1309             auto tmpPixelMap = PixelMap::Create(*(context->rPixelMap), opts);
1310             context->alphaMap = std::move(tmpPixelMap);
1311             context->status = SUCCESS;
1312         }, CreateAlphaPixelmapComplete, asyncContext, asyncContext->work);
1313     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1314         nullptr, HiLog::Error(LABEL, "fail to create async work"));
1315     return result;
1316 }
1317 
GetDensity(napi_env env,napi_callback_info info)1318 napi_value PixelMapNapi::GetDensity(napi_env env, napi_callback_info info)
1319 {
1320     napi_value result = nullptr;
1321     napi_get_undefined(env, &result);
1322 
1323     napi_status status;
1324     napi_value thisVar = nullptr;
1325     size_t argCount = 0;
1326 
1327     HiLog::Debug(LABEL, "GetDensity IN");
1328     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
1329 
1330     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1331 
1332     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1333     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1334 
1335     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
1336     if (pixelMapNapi->nativePixelMap_ != nullptr) {
1337         uint32_t baseDensity = pixelMapNapi->nativePixelMap_->GetBaseDensity();
1338         status = napi_create_int32(env, baseDensity, &result);
1339         if (!IMG_IS_OK(status)) {
1340             HiLog::Error(LABEL, "napi_create_int32 failed!");
1341         }
1342     } else {
1343         HiLog::Error(LABEL, "native pixelmap is nullptr!");
1344     }
1345     pixelMapNapi.release();
1346     return result;
1347 }
1348 
SetDensity(napi_env env,napi_callback_info info)1349 napi_value PixelMapNapi::SetDensity(napi_env env, napi_callback_info info)
1350 {
1351     napi_value result = nullptr;
1352     napi_get_undefined(env, &result);
1353 
1354     napi_status status;
1355     napi_value thisVar = nullptr;
1356     napi_value argValue[NUM_1] = {0};
1357     size_t argCount = NUM_1;
1358     uint32_t density = 0;
1359 
1360     HiLog::Debug(LABEL, "SetDensity IN");
1361     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1362     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1363 
1364     NAPI_ASSERT(env,
1365         (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number),
1366         "Density input mismatch");
1367     NAPI_ASSERT(env, napi_get_value_uint32(env, argValue[NUM_0], &density) == napi_ok, "Could not parse density");
1368 
1369     std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
1370     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
1371 
1372     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
1373     if (pixelMapNapi->nativePixelMap_ != nullptr) {
1374         ImageInfo imageinfo;
1375         pixelMapNapi->nativePixelMap_->GetImageInfo(imageinfo);
1376         imageinfo.baseDensity = density;
1377         pixelMapNapi->nativePixelMap_->SetImageInfo(imageinfo, true);
1378     } else {
1379         HiLog::Error(LABEL, "native pixelmap is nullptr!");
1380     }
1381     pixelMapNapi.release();
1382     return result;
1383 }
1384 
Release(napi_env env,napi_callback_info info)1385 napi_value PixelMapNapi::Release(napi_env env, napi_callback_info info)
1386 {
1387     napi_value result = nullptr;
1388     napi_get_undefined(env, &result);
1389 
1390     int32_t refCount = 1;
1391     napi_status status;
1392     napi_value thisVar = nullptr;
1393     napi_value argValue[1] = {0};
1394     size_t argCount = 1;
1395 
1396     HiLog::Debug(LABEL, "Release IN");
1397     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1398 
1399     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1400 
1401     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1402     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1403 
1404     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1405         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
1406 
1407     if (argCount == 1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1408         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1409     }
1410 
1411     if (asyncContext->callbackRef == nullptr) {
1412         napi_create_promise(env, &(asyncContext->deferred), &result);
1413     } else {
1414         napi_get_undefined(env, &result);
1415     }
1416 
1417     if (asyncContext->nConstructor->IsLockPixelMap()) {
1418         asyncContext->status = ERROR;
1419     } else {
1420         if (asyncContext->nConstructor->nativePixelMap_ != nullptr
1421             && asyncContext->nConstructor->nativePixelMap_ == asyncContext->nConstructor->nativeInner_)
1422         {
1423             asyncContext->nConstructor->nativePixelMap_ = nullptr;
1424             asyncContext->nConstructor->nativeInner_ = nullptr;
1425         }
1426         asyncContext->status = SUCCESS;
1427     }
1428     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "Release",
1429         [](napi_env env, void *data)
1430         {
1431         }, EmptyResultComplete, asyncContext, asyncContext->work);
1432 
1433     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1434         nullptr, HiLog::Error(LABEL, "fail to create async work"));
1435     return result;
1436 }
1437 
1438 struct NapiValues {
1439     napi_status status;
1440     napi_value thisVar = nullptr;
1441     napi_value result = nullptr;
1442     napi_value* argv = nullptr;
1443     size_t argc;
1444     int32_t refCount = 1;
1445     std::unique_ptr<PixelMapAsyncContext> context;
1446 };
1447 
prepareNapiEnv(napi_env env,napi_callback_info info,struct NapiValues * nVal)1448 static bool prepareNapiEnv(napi_env env, napi_callback_info info, struct NapiValues* nVal)
1449 {
1450     napi_get_undefined(env, &(nVal->result));
1451     nVal->status = napi_get_cb_info(env, info, &(nVal->argc), nVal->argv, &(nVal->thisVar), nullptr);
1452     if (nVal->status != napi_ok) {
1453         HiLog::Error(LABEL, "fail to napi_get_cb_info");
1454         return false;
1455     }
1456     nVal->context = std::make_unique<PixelMapAsyncContext>();
1457     nVal->status = napi_unwrap(env, nVal->thisVar, reinterpret_cast<void**>(&(nVal->context->nConstructor)));
1458     if (nVal->status != napi_ok) {
1459         HiLog::Error(LABEL, "fail to unwrap context");
1460         return false;
1461     }
1462     nVal->context->status = SUCCESS;
1463     return true;
1464 }
1465 
SetAlphaExec(napi_env env,PixelMapAsyncContext * context)1466 static void SetAlphaExec(napi_env env, PixelMapAsyncContext* context)
1467 {
1468     if (context == nullptr) {
1469         HiLog::Error(LABEL, "Null context");
1470         return;
1471     }
1472     if (context->status == SUCCESS) {
1473         if (context->rPixelMap != nullptr) {
1474             context->status = context->rPixelMap->SetAlpha(
1475                 static_cast<float>(context->alpha));
1476         } else {
1477             HiLog::Error(LABEL, "Null native ref");
1478             context->status = ERR_IMAGE_INIT_ABNORMAL;
1479         }
1480     } else {
1481         HiLog::Debug(LABEL, "Scale has failed. do nothing");
1482     }
1483 }
1484 
SetAlpha(napi_env env,napi_callback_info info)1485 napi_value PixelMapNapi::SetAlpha(napi_env env, napi_callback_info info)
1486 {
1487     NapiValues nVal;
1488     nVal.argc = NUM_2;
1489     napi_value argValue[NUM_2] = {0};
1490     nVal.argv = argValue;
1491 
1492     HiLog::Debug(LABEL, "SetAlpha IN");
1493     if (!prepareNapiEnv(env, info, &nVal)) {
1494         return nVal.result;
1495     }
1496     nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1497 
1498     if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
1499         HiLog::Error(LABEL, "Invalid args count %{public}zu", nVal.argc);
1500         nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1501     } else {
1502         if (napi_ok !=
1503             napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->alpha))) {
1504             HiLog::Error(LABEL, "Arg 0 type mismatch");
1505             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1506         }
1507     }
1508     if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1509         napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1510     }
1511 
1512     if (nVal.context->callbackRef == nullptr) {
1513         napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1514     }
1515     napi_value _resource = nullptr;
1516     napi_create_string_utf8(env, "SetAlpha", NAPI_AUTO_LENGTH, &_resource);
1517     nVal.status = napi_create_async_work(env, nullptr, _resource,
1518         [](napi_env env, void *data)
1519         {
1520             auto context = static_cast<PixelMapAsyncContext*>(data);
1521             SetAlphaExec(env, context);
1522         }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1523 
1524     if (nVal.status == napi_ok) {
1525         nVal.status = napi_queue_async_work(env, nVal.context->work);
1526         if (nVal.status == napi_ok) {
1527             nVal.context.release();
1528         }
1529     }
1530     return nVal.result;
1531 }
1532 
ScaleExec(napi_env env,PixelMapAsyncContext * context)1533 static void ScaleExec(napi_env env, PixelMapAsyncContext* context)
1534 {
1535     if (context == nullptr) {
1536         HiLog::Error(LABEL, "Null context");
1537         return;
1538     }
1539     if (context->status == SUCCESS) {
1540         if (context->rPixelMap != nullptr) {
1541 
1542             context->rPixelMap->scale(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
1543             context->status = SUCCESS;
1544         } else {
1545             HiLog::Error(LABEL, "Null native ref");
1546             context->status = ERR_IMAGE_INIT_ABNORMAL;
1547         }
1548     } else {
1549         HiLog::Debug(LABEL, "Scale has failed. do nothing");
1550     }
1551 }
1552 
Scale(napi_env env,napi_callback_info info)1553 napi_value PixelMapNapi::Scale(napi_env env, napi_callback_info info)
1554 {
1555     NapiValues nVal;
1556     nVal.argc = NUM_3;
1557     napi_value argValue[NUM_3] = {0};
1558     nVal.argv = argValue;
1559     HiLog::Debug(LABEL, "Scale IN");
1560     if (!prepareNapiEnv(env, info, &nVal)) {
1561         return nVal.result;
1562     }
1563     nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1564 
1565     if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
1566         HiLog::Error(LABEL, "Invalid args count %{public}zu", nVal.argc);
1567         nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1568     } else {
1569         if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
1570             HiLog::Error(LABEL, "Arg 0 type mismatch");
1571             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1572         }
1573         if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
1574             HiLog::Error(LABEL, "Arg 1 type mismatch");
1575             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1576         }
1577     }
1578     if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1579         napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1580     }
1581 
1582     if (nVal.context->callbackRef == nullptr) {
1583         napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1584     }
1585     napi_value _resource = nullptr;
1586     napi_create_string_utf8(env, "Scale", NAPI_AUTO_LENGTH, &_resource);
1587     nVal.status = napi_create_async_work(env, nullptr, _resource,
1588         [](napi_env env, void *data)
1589         {
1590             auto context = static_cast<PixelMapAsyncContext*>(data);
1591             ScaleExec(env, context);
1592         }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1593 
1594     if (nVal.status == napi_ok) {
1595         nVal.status = napi_queue_async_work_with_qos(env, nVal.context->work, napi_qos_user_initiated);
1596         if (nVal.status == napi_ok) {
1597             nVal.context.release();
1598         }
1599     }
1600     return nVal.result;
1601 }
1602 
TranslateExec(napi_env env,PixelMapAsyncContext * context)1603 static void TranslateExec(napi_env env, PixelMapAsyncContext* context)
1604 {
1605     if (context == nullptr) {
1606         HiLog::Error(LABEL, "Null context");
1607         return;
1608     }
1609     if (context->status == SUCCESS) {
1610         if (context->rPixelMap != nullptr) {
1611             context->rPixelMap->translate(static_cast<float>(context->xArg), static_cast<float>(context->yArg));
1612             context->status = SUCCESS;
1613         } else {
1614             HiLog::Error(LABEL, "Null native ref");
1615             context->status = ERR_IMAGE_INIT_ABNORMAL;
1616         }
1617     } else {
1618         HiLog::Debug(LABEL, "Translate has failed. do nothing");
1619     }
1620 }
1621 
Translate(napi_env env,napi_callback_info info)1622 napi_value PixelMapNapi::Translate(napi_env env, napi_callback_info info)
1623 {
1624     NapiValues nVal;
1625     nVal.argc = NUM_3;
1626     napi_value argValue[NUM_3] = {0};
1627     nVal.argv = argValue;
1628     HiLog::Debug(LABEL, "Translate IN");
1629     if (!prepareNapiEnv(env, info, &nVal)) {
1630         return nVal.result;
1631     }
1632     nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1633 
1634     if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
1635         HiLog::Error(LABEL, "Invalid args count");
1636         nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1637     } else {
1638         if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
1639             HiLog::Error(LABEL, "Arg 0 type mismatch");
1640             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1641         }
1642         if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_1], &(nVal.context->yArg))) {
1643             HiLog::Error(LABEL, "Arg 1 type mismatch");
1644             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1645         }
1646     }
1647     if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1648         napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1649     }
1650 
1651     if (nVal.context->callbackRef == nullptr) {
1652         napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1653     }
1654     napi_value _resource = nullptr;
1655     napi_create_string_utf8(env, "Translate", NAPI_AUTO_LENGTH, &_resource);
1656     nVal.status = napi_create_async_work(env, nullptr, _resource,
1657         [](napi_env env, void *data)
1658         {
1659             auto context = static_cast<PixelMapAsyncContext*>(data);
1660             TranslateExec(env, context);
1661         }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1662 
1663     if (nVal.status == napi_ok) {
1664         nVal.status = napi_queue_async_work(env, nVal.context->work);
1665         if (nVal.status == napi_ok) {
1666             nVal.context.release();
1667         }
1668     }
1669     return nVal.result;
1670 }
1671 
RotateExec(napi_env env,PixelMapAsyncContext * context)1672 static void RotateExec(napi_env env, PixelMapAsyncContext* context)
1673 {
1674     if (context == nullptr) {
1675         HiLog::Error(LABEL, "Null context");
1676         return;
1677     }
1678     if (context->status == SUCCESS) {
1679         if (context->rPixelMap != nullptr) {
1680             context->rPixelMap->rotate(context->xArg);
1681             context->status = SUCCESS;
1682         } else {
1683             HiLog::Error(LABEL, "Null native ref");
1684             context->status = ERR_IMAGE_INIT_ABNORMAL;
1685         }
1686     } else {
1687         HiLog::Debug(LABEL, "Rotate has failed. do nothing");
1688     }
1689 }
1690 
Rotate(napi_env env,napi_callback_info info)1691 napi_value PixelMapNapi::Rotate(napi_env env, napi_callback_info info)
1692 {
1693     NapiValues nVal;
1694     nVal.argc = NUM_2;
1695     napi_value argValue[NUM_2] = {0};
1696     nVal.argv = argValue;
1697     HiLog::Debug(LABEL, "Rotate IN");
1698     if (!prepareNapiEnv(env, info, &nVal)) {
1699         return nVal.result;
1700     }
1701     nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1702 
1703     if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
1704         HiLog::Error(LABEL, "Invalid args count");
1705         nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1706     } else {
1707         if (napi_ok != napi_get_value_double(env, nVal.argv[NUM_0], &(nVal.context->xArg))) {
1708             HiLog::Error(LABEL, "Arg 0 type mismatch");
1709             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1710         }
1711     }
1712     if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1713         napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1714     }
1715 
1716     if (nVal.context->callbackRef == nullptr) {
1717         napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1718     }
1719     napi_value _resource = nullptr;
1720     napi_create_string_utf8(env, "Rotate", NAPI_AUTO_LENGTH, &_resource);
1721     nVal.status = napi_create_async_work(env, nullptr, _resource,
1722         [](napi_env env, void *data)
1723         {
1724             auto context = static_cast<PixelMapAsyncContext*>(data);
1725             RotateExec(env, context);
1726         }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1727 
1728     if (nVal.status == napi_ok) {
1729         nVal.status = napi_queue_async_work(env, nVal.context->work);
1730         if (nVal.status == napi_ok) {
1731             nVal.context.release();
1732         }
1733     }
1734     return nVal.result;
1735 }
1736 
FlipExec(napi_env env,PixelMapAsyncContext * context)1737 static void FlipExec(napi_env env, PixelMapAsyncContext* context)
1738 {
1739     if (context == nullptr) {
1740         HiLog::Error(LABEL, "Null context");
1741         return;
1742     }
1743     if (context->status == SUCCESS) {
1744         if (context->rPixelMap != nullptr) {
1745             context->rPixelMap->flip(context->xBarg, context->yBarg);
1746             context->status = SUCCESS;
1747         } else {
1748             HiLog::Error(LABEL, "Null native ref");
1749             context->status = ERR_IMAGE_INIT_ABNORMAL;
1750         }
1751     } else {
1752         HiLog::Debug(LABEL, "Flip has failed. do nothing");
1753     }
1754 }
1755 
Flip(napi_env env,napi_callback_info info)1756 napi_value PixelMapNapi::Flip(napi_env env, napi_callback_info info)
1757 {
1758     NapiValues nVal;
1759     nVal.argc = NUM_3;
1760     napi_value argValue[NUM_3] = {0};
1761     nVal.argv = argValue;
1762     HiLog::Debug(LABEL, "Flip IN");
1763     if (!prepareNapiEnv(env, info, &nVal)) {
1764         return nVal.result;
1765     }
1766     nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1767 
1768     if (nVal.argc != NUM_2 && nVal.argc != NUM_3) {
1769         HiLog::Error(LABEL, "Invalid args count");
1770         nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1771     } else {
1772         if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_0], &(nVal.context->xBarg))) {
1773             HiLog::Error(LABEL, "Arg 0 type mismatch");
1774             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1775         }
1776         if (napi_ok != napi_get_value_bool(env, nVal.argv[NUM_1], &(nVal.context->yBarg))) {
1777             HiLog::Error(LABEL, "Arg 1 type mismatch");
1778             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1779         }
1780     }
1781     if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1782         napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1783     }
1784 
1785     if (nVal.context->callbackRef == nullptr) {
1786         napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1787     }
1788     napi_value _resource = nullptr;
1789     napi_create_string_utf8(env, "Flip", NAPI_AUTO_LENGTH, &_resource);
1790     nVal.status = napi_create_async_work(env, nullptr, _resource,
1791         [](napi_env env, void *data)
1792         {
1793             auto context = static_cast<PixelMapAsyncContext*>(data);
1794             FlipExec(env, context);
1795         }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1796 
1797     if (nVal.status == napi_ok) {
1798         nVal.status = napi_queue_async_work(env, nVal.context->work);
1799         if (nVal.status == napi_ok) {
1800             nVal.context.release();
1801         }
1802     }
1803     return nVal.result;
1804 }
1805 
CropExec(napi_env env,PixelMapAsyncContext * context)1806 static void CropExec(napi_env env, PixelMapAsyncContext* context)
1807 {
1808     if (context == nullptr) {
1809         HiLog::Error(LABEL, "Null context");
1810         return;
1811     }
1812     if (context->status == SUCCESS) {
1813         if (context->rPixelMap != nullptr) {
1814             context->status = context->rPixelMap->crop(context->area.region);
1815         } else {
1816             HiLog::Error(LABEL, "Null native ref");
1817             context->status = ERR_IMAGE_INIT_ABNORMAL;
1818         }
1819     } else {
1820         HiLog::Debug(LABEL, "Crop has failed. do nothing");
1821     }
1822 }
1823 
Crop(napi_env env,napi_callback_info info)1824 napi_value PixelMapNapi::Crop(napi_env env, napi_callback_info info)
1825 {
1826     NapiValues nVal;
1827     nVal.argc = NUM_2;
1828     napi_value argValue[NUM_2] = {0};
1829     nVal.argv = argValue;
1830     HiLog::Debug(LABEL, "Crop IN");
1831     if (!prepareNapiEnv(env, info, &nVal)) {
1832         return nVal.result;
1833     }
1834     nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1835 
1836     if (nVal.argc != NUM_1 && nVal.argc != NUM_2) {
1837         HiLog::Error(LABEL, "Invalid args count");
1838         nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1839     } else {
1840         if (!parseRegion(env, nVal.argv[NUM_0], &(nVal.context->area.region))) {
1841             HiLog::Error(LABEL, "Region type mismatch");
1842             nVal.context->status = ERR_IMAGE_INVALID_PARAMETER;
1843         }
1844     }
1845     if (nVal.argc >= 1 && ImageNapiUtils::getType(env, nVal.argv[nVal.argc - 1]) == napi_function) {
1846         napi_create_reference(env, nVal.argv[nVal.argc - 1], nVal.refCount, &(nVal.context->callbackRef));
1847     }
1848 
1849     if (nVal.context->callbackRef == nullptr) {
1850         napi_create_promise(env, &(nVal.context->deferred), &(nVal.result));
1851     }
1852     napi_value _resource = nullptr;
1853     napi_create_string_utf8(env, "CropExec", NAPI_AUTO_LENGTH, &_resource);
1854     nVal.status = napi_create_async_work(env, nullptr, _resource,
1855         [](napi_env env, void *data)
1856         {
1857             auto context = static_cast<PixelMapAsyncContext*>(data);
1858             CropExec(env, context);
1859         }, EmptyResultComplete, static_cast<void*>(nVal.context.get()), &(nVal.context->work));
1860 
1861     if (nVal.status == napi_ok) {
1862         nVal.status = napi_queue_async_work(env, nVal.context->work);
1863         if (nVal.status == napi_ok) {
1864             nVal.context.release();
1865         }
1866     }
1867     return nVal.result;
1868 }
1869 
GetColorSpace(napi_env env,napi_callback_info info)1870 napi_value PixelMapNapi::GetColorSpace(napi_env env, napi_callback_info info)
1871 {
1872     NapiValues nVal;
1873     nVal.argc = NUM_0;
1874     HiLog::Debug(LABEL, "GetColorSpace IN");
1875     napi_get_undefined(env, &nVal.result);
1876     if (!prepareNapiEnv(env, info, &nVal)) {
1877         return ImageNapiUtils::ThrowExceptionError(
1878             env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
1879     }
1880     if (nVal.argc != NUM_0) {
1881         return ImageNapiUtils::ThrowExceptionError(
1882             env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
1883     }
1884 #ifdef IMAGE_COLORSPACE_FLAG
1885     if (nVal.context->nConstructor->nativePixelMap_ == nullptr) {
1886         return ImageNapiUtils::ThrowExceptionError(
1887             env, ERR_IMAGE_DATA_ABNORMAL, "Invalid native pixelmap");
1888     }
1889     auto grCS = nVal.context->nConstructor->nativePixelMap_->InnerGetGrColorSpacePtr();
1890     if (grCS == nullptr) {
1891         return ImageNapiUtils::ThrowExceptionError(
1892             env, ERR_IMAGE_DATA_UNSUPPORT, "No colorspace in pixelmap");
1893     }
1894     auto engine = reinterpret_cast<NativeEngine*>(env);
1895     auto resultValue = ColorManager::CreateJsColorSpaceObject(*engine, grCS);
1896     nVal.result = reinterpret_cast<napi_value>(resultValue);
1897 #else
1898     return ImageNapiUtils::ThrowExceptionError(
1899         env, ERR_INVALID_OPERATION, "Unsupported operation");
1900 #endif
1901     return nVal.result;
1902 }
1903 
SetColorSpace(napi_env env,napi_callback_info info)1904 napi_value PixelMapNapi::SetColorSpace(napi_env env, napi_callback_info info)
1905 {
1906     NapiValues nVal;
1907     nVal.argc = NUM_1;
1908     napi_value argValue[NUM_1] = {0};
1909     nVal.argv = argValue;
1910     HiLog::Debug(LABEL, "SetColorSpace IN");
1911     napi_get_undefined(env, &nVal.result);
1912     if (!prepareNapiEnv(env, info, &nVal)) {
1913         return ImageNapiUtils::ThrowExceptionError(
1914             env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
1915     }
1916     if (nVal.argc != NUM_1) {
1917         return ImageNapiUtils::ThrowExceptionError(
1918             env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
1919     }
1920 #ifdef IMAGE_COLORSPACE_FLAG
1921 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
1922     auto csNativeValue = reinterpret_cast<NativeValue*>(nVal.argv[NUM_0]);
1923     auto csNativeObject = OHOS::AbilityRuntime::ConvertNativeValueTo<NativeObject>(csNativeValue);
1924     nVal.context->colorSpace = ColorManager::GetColorSpaceByJSObject(csNativeObject);
1925 #endif
1926     if (nVal.context->colorSpace == nullptr) {
1927         return ImageNapiUtils::ThrowExceptionError(
1928             env, ERR_IMAGE_INVALID_PARAMETER, "ColorSpace mismatch");
1929     }
1930     nVal.context->nConstructor->nativePixelMap_->InnerSetColorSpace(*(nVal.context->colorSpace));
1931 #else
1932     return ImageNapiUtils::ThrowExceptionError(
1933         env, ERR_INVALID_OPERATION, "Unsupported operation");
1934 #endif
1935     return nVal.result;
1936 }
1937 
Marshalling(napi_env env,napi_callback_info info)1938 napi_value PixelMapNapi::Marshalling(napi_env env, napi_callback_info info)
1939 {
1940 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
1941     NapiValues nVal;
1942     nVal.argc = NUM_1;
1943     napi_value argValue[NUM_1] = {0};
1944     nVal.argv = argValue;
1945     HiLog::Debug(LABEL, "Marshalling IN");
1946 
1947     if (!prepareNapiEnv(env, info, &nVal)) {
1948         return ImageNapiUtils::ThrowExceptionError(
1949             env, ERR_IMAGE_INVALID_PARAMETER, "Fail to unwrap context");
1950     }
1951     nVal.context->rPixelMap = nVal.context->nConstructor->nativePixelMap_;
1952     if (nVal.argc != NUM_0 && nVal.argc != NUM_1) {
1953         return ImageNapiUtils::ThrowExceptionError(
1954             env, ERR_IMAGE_INVALID_PARAMETER, "Invalid args count");
1955     }
1956     NAPI_MessageSequence *napiSequence = nullptr;
1957     napi_get_cb_info(env, info, &nVal.argc, nVal.argv, nullptr, nullptr);
1958     napi_unwrap(env, nVal.argv[0], reinterpret_cast<void**>(&napiSequence));
1959     auto messageParcel = napiSequence->GetMessageParcel();
1960     bool st = nVal.context->rPixelMap->Marshalling(*messageParcel);
1961     if (!st) {
1962         return ImageNapiUtils::ThrowExceptionError(
1963             env, ERR_IPC, "marshalling pixel map to parcel failed.");
1964     }
1965     return nVal.result;
1966 #else
1967     napi_value result = nullptr;
1968     return result;
1969 #endif
1970 }
1971 
release()1972 void PixelMapNapi::release()
1973 {
1974     if (!isRelease) {
1975         if (nativePixelMap_ != nullptr) {
1976             nativePixelMap_ = nullptr;
1977             nativeInner_ = nullptr;
1978         }
1979         isRelease = true;
1980     }
1981 }
1982 }  // namespace Media
1983 }  // namespace OHOS
1984