• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 
22 using OHOS::HiviewDFX::HiLog;
23 namespace {
24     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "PixelMapNapi"};
25     constexpr uint32_t NUM_0 = 0;
26     constexpr uint32_t NUM_1 = 1;
27     constexpr uint32_t NUM_2 = 2;
28     constexpr uint32_t NUM_3 = 3;
29     constexpr uint32_t NUM_4 = 4;
30 }
31 
32 namespace OHOS {
33 namespace Media {
34 
35 static const std::string CLASS_NAME = "PixelMap";
36 thread_local napi_ref PixelMapNapi::sConstructor_ = nullptr;
37 std::shared_ptr<PixelMap> PixelMapNapi::sPixelMap_ = nullptr;
38 
39 struct PositionArea {
40     void* pixels;
41     size_t size;
42     uint32_t offset;
43     uint32_t stride;
44     Rect region;
45 };
46 
47 struct PixelMapAsyncContext {
48     napi_env env;
49     napi_async_work work;
50     napi_deferred deferred;
51     napi_ref callbackRef;
52     uint32_t status;
53     PixelMapNapi *nConstructor;
54     void* colorsBuffer;
55     size_t colorsBufferSize;
56     InitializationOptions opts;
57     PositionArea area;
58     std::shared_ptr<PixelMap> rPixelMap;
59     uint32_t resultUint32;
60     ImageInfo imageInfo;
61 };
62 
ParsePixlForamt(int32_t val)63 static PixelFormat ParsePixlForamt(int32_t val)
64 {
65     if (val <= static_cast<int32_t>(PixelFormat::CMYK)) {
66         return PixelFormat(val);
67     }
68 
69     return PixelFormat::UNKNOWN;
70 }
71 
ParseAlphaType(int32_t val)72 static AlphaType ParseAlphaType(int32_t val)
73 {
74     if (val <= static_cast<int32_t>(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
75         return AlphaType(val);
76     }
77 
78     return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
79 
80 }
81 
ParseScaleMode(int32_t val)82 static ScaleMode ParseScaleMode(int32_t val)
83 {
84     if (val <= static_cast<int32_t>(ScaleMode::CENTER_CROP)) {
85         return ScaleMode(val);
86     }
87 
88     return ScaleMode::FIT_TARGET_SIZE;
89 }
90 
parseSize(napi_env env,napi_value root,Size * size)91 static bool parseSize(napi_env env, napi_value root, Size* size)
92 {
93     if (!GET_INT32_BY_NAME(root, "height", size->height)) {
94         return false;
95     }
96 
97     if (!GET_INT32_BY_NAME(root, "width", size->width)) {
98         return false;
99     }
100 
101     return true;
102 }
103 
parseInitializationOptions(napi_env env,napi_value root,InitializationOptions * opts)104 static bool parseInitializationOptions(napi_env env, napi_value root, InitializationOptions* opts)
105 {
106     uint32_t tmpNumber = 0;
107     napi_value tmpValue = nullptr;
108 
109     if (!GET_BOOL_BY_NAME(root, "editable", opts->editable)) {
110         HiLog::Info(LABEL, "no editable in initialization options");
111         opts->editable = true;
112     }
113 
114     if (!GET_UINT32_BY_NAME(root, "alphaType", tmpNumber)) {
115         HiLog::Info(LABEL, "no alphaType in initialization options");
116     }
117     opts->alphaType = ParseAlphaType(tmpNumber);
118 
119     tmpNumber = 0;
120     if (!GET_UINT32_BY_NAME(root, "pixelFormat", tmpNumber)) {
121         HiLog::Info(LABEL, "no pixelFormat in initialization options");
122     }
123     opts->pixelFormat = ParsePixlForamt(tmpNumber);
124 
125 
126     tmpNumber = 0;
127     if (!GET_UINT32_BY_NAME(root, "scaleMode", tmpNumber)) {
128         HiLog::Info(LABEL, "no scaleMode in initialization options");
129     }
130     opts->scaleMode = ParseScaleMode(tmpNumber);
131 
132     if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
133         return false;
134     }
135 
136     if (!parseSize(env, tmpValue, &(opts->size))) {
137         return false;
138     }
139     return true;
140 }
141 
parseRegion(napi_env env,napi_value root,Rect * region)142 static bool parseRegion(napi_env env, napi_value root, Rect* region)
143 {
144     napi_value tmpValue = nullptr;
145 
146     if (!GET_INT32_BY_NAME(root, "x", region->left)) {
147         return false;
148     }
149 
150     if (!GET_INT32_BY_NAME(root, "y", region->top)) {
151         return false;
152     }
153 
154     if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
155         return false;
156     }
157 
158     if (!GET_INT32_BY_NAME(tmpValue, "height", region->height)) {
159         return false;
160     }
161 
162     if (!GET_INT32_BY_NAME(tmpValue, "width", region->width)) {
163         return false;
164     }
165 
166     return true;
167 }
168 
parsePositionArea(napi_env env,napi_value root,PositionArea * area)169 static bool parsePositionArea(napi_env env, napi_value root, PositionArea* area)
170 {
171     napi_value tmpValue = nullptr;
172 
173     if (!GET_BUFFER_BY_NAME(root, "pixels", area->pixels, area->size)) {
174         return false;
175     }
176 
177     if (!GET_UINT32_BY_NAME(root, "offset", area->offset)) {
178         return false;
179     }
180 
181     if (!GET_UINT32_BY_NAME(root, "stride", area->stride)) {
182         return false;
183     }
184 
185     if (!GET_NODE_BY_NAME(root, "region", tmpValue)) {
186         return false;
187     }
188 
189     if (!parseRegion(env, tmpValue, &(area->region))) {
190         return false;
191     }
192     return true;
193 }
194 
CommonCallbackRoutine(napi_env env,PixelMapAsyncContext * & asyncContext,const napi_value & valueParam)195 static void CommonCallbackRoutine(napi_env env, PixelMapAsyncContext* &asyncContext, const napi_value &valueParam)
196 {
197     napi_value result[NUM_2] = {0};
198     napi_value retVal;
199     napi_value callback = nullptr;
200 
201     napi_get_undefined(env, &result[NUM_0]);
202     napi_get_undefined(env, &result[NUM_1]);
203 
204     if (asyncContext->status == SUCCESS) {
205         result[NUM_1] = valueParam;
206     }
207 
208     if (asyncContext->deferred) {
209         if (asyncContext->status == SUCCESS) {
210             napi_resolve_deferred(env, asyncContext->deferred, result[NUM_1]);
211         } else {
212             napi_reject_deferred(env, asyncContext->deferred, result[NUM_0]);
213         }
214     } else {
215         napi_get_reference_value(env, asyncContext->callbackRef, &callback);
216         napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
217         napi_delete_reference(env, asyncContext->callbackRef);
218     }
219 
220     napi_delete_async_work(env, asyncContext->work);
221 
222     delete asyncContext;
223     asyncContext = nullptr;
224 }
225 
STATIC_COMPLETE_FUNC(EmptyResult)226 STATIC_COMPLETE_FUNC(EmptyResult)
227 {
228     napi_value result = nullptr;
229     napi_get_undefined(env, &result);
230 
231     auto context = static_cast<PixelMapAsyncContext*>(data);
232 
233     CommonCallbackRoutine(env, context, result);
234 }
235 
PixelMapNapi()236 PixelMapNapi::PixelMapNapi()
237     :env_(nullptr), wrapper_(nullptr)
238 {
239 
240 }
241 
~PixelMapNapi()242 PixelMapNapi::~PixelMapNapi()
243 {
244     if (nativePixelMap_ != nullptr) {
245         nativePixelMap_ = nullptr;
246     }
247 
248     if (wrapper_ != nullptr) {
249         napi_delete_reference(env_, wrapper_);
250     }
251 }
252 
Init(napi_env env,napi_value exports)253 napi_value PixelMapNapi::Init(napi_env env, napi_value exports)
254 {
255     napi_property_descriptor props[] = {
256         DECLARE_NAPI_FUNCTION("readPixelsToBuffer", ReadPixelsToBuffer),
257         DECLARE_NAPI_FUNCTION("readPixels", ReadPixels),
258         DECLARE_NAPI_FUNCTION("writePixels", WritePixels),
259         DECLARE_NAPI_FUNCTION("writeBufferToPixels", WriteBufferToPixels),
260         DECLARE_NAPI_FUNCTION("getImageInfo", GetImageInfo),
261         DECLARE_NAPI_FUNCTION("getBytesNumberPerRow", GetBytesNumberPerRow),
262         DECLARE_NAPI_FUNCTION("getPixelBytesNumber", GetPixelBytesNumber),
263         DECLARE_NAPI_FUNCTION("release", Release),
264 
265         DECLARE_NAPI_GETTER("isEditable", GetIsEditable),
266     };
267 
268     napi_property_descriptor static_prop[] = {
269         DECLARE_NAPI_STATIC_FUNCTION("createPixelMap", CreatePixelMap),
270     };
271 
272     napi_value constructor = nullptr;
273 
274     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
275         napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
276                           Constructor, nullptr, IMG_ARRAY_SIZE(props),
277                           props, &constructor)),
278         nullptr,
279         HiLog::Error(LABEL, "define class fail")
280     );
281 
282     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
283         napi_create_reference(env, constructor, 1, &sConstructor_)),
284         nullptr,
285         HiLog::Error(LABEL, "create reference fail")
286     );
287 
288     napi_value global = nullptr;
289     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
290         napi_get_global(env, &global)),
291         nullptr,
292         HiLog::Error(LABEL, "Init:get global fail")
293     );
294 
295     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
296         napi_set_named_property(env, global, CLASS_NAME.c_str(), constructor)),
297         nullptr,
298         HiLog::Error(LABEL, "Init:set global named property fail")
299     );
300 
301     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
302         napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor)),
303         nullptr,
304         HiLog::Error(LABEL, "set named property fail")
305     );
306 
307     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(
308         napi_define_properties(env, exports, IMG_ARRAY_SIZE(static_prop), static_prop)),
309         nullptr,
310         HiLog::Error(LABEL, "define properties fail")
311     );
312 
313     HiLog::Debug(LABEL, "Init success");
314     return exports;
315 }
316 
GetPixelMap(napi_env env,napi_value pixelmap)317 std::shared_ptr<PixelMap> PixelMapNapi::GetPixelMap(napi_env env, napi_value pixelmap)
318 {
319     std::unique_ptr<PixelMapNapi> pixelMapNapi = std::make_unique<PixelMapNapi>();
320 
321     napi_status status = napi_unwrap(env, pixelmap, reinterpret_cast<void**>(&pixelMapNapi));
322     if (!IMG_IS_OK(status)) {
323         HiLog::Error(LABEL, "GetPixelMap napi unwrap failed");
324         return nullptr;
325     }
326 
327     if (pixelMapNapi == nullptr) {
328         HiLog::Error(LABEL, "GetPixelMap pixmapNapi is nullptr");
329         return nullptr;
330     }
331 
332     return pixelMapNapi->nativePixelMap_;
333 }
334 
GetPixelMap()335 std::shared_ptr<PixelMap>* PixelMapNapi::GetPixelMap()
336 {
337     return &nativePixelMap_;
338 }
339 
IsLockPixelMap()340 bool PixelMapNapi::IsLockPixelMap()
341 {
342     return (lockCount > 0);
343 }
344 
LockPixelMap()345 bool PixelMapNapi::LockPixelMap()
346 {
347     lockCount++;
348     return true;
349 }
350 
UnlockPixelMap()351 void PixelMapNapi::UnlockPixelMap()
352 {
353     if (lockCount > 0) {
354         lockCount--;
355     }
356 }
357 
OHOS_MEDIA_GetPixelMap(napi_env env,napi_value value)358 extern "C" __attribute__((visibility("default"))) void* OHOS_MEDIA_GetPixelMap(napi_env env, napi_value value)
359 {
360     PixelMapNapi *pixmapNapi = nullptr;
361     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
362     if (pixmapNapi == nullptr) {
363         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
364         return nullptr;
365     }
366     return reinterpret_cast<void*>(pixmapNapi->GetPixelMap());
367 }
368 
OHOS_MEDIA_GetImageInfo(napi_env env,napi_value value,OhosPixelMapInfo * info)369 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_GetImageInfo(napi_env env, napi_value value,
370     OhosPixelMapInfo *info)
371 {
372     HiLog::Debug(LABEL, "GetImageInfo IN");
373 
374     if (info == nullptr) {
375         HiLog::Error(LABEL, "info is nullptr");
376         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
377     }
378 
379     PixelMapNapi *pixmapNapi = nullptr;
380     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
381     if (pixmapNapi == nullptr) {
382         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
383         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
384     }
385 
386     std::shared_ptr<PixelMap> *pixelMap = pixmapNapi->GetPixelMap();
387     if ((pixelMap == nullptr) || ((*pixelMap) == nullptr)) {
388         HiLog::Error(LABEL, "pixelMap is nullptr");
389         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
390     }
391 
392     ImageInfo imageInfo;
393     (*pixelMap)->GetImageInfo(imageInfo);
394     info->width = imageInfo.size.width;
395     info->height = imageInfo.size.height;
396     info->rowSize = (*pixelMap)->GetRowBytes();
397     info->pixelFormat = static_cast<int32_t>(imageInfo.pixelFormat);
398 
399     HiLog::Debug(LABEL, "GetImageInfo, w=%{public}u, h=%{public}u, r=%{public}u, f=%{public}d",
400         info->width, info->height, info->rowSize, info->pixelFormat);
401 
402     HiLog::Debug(LABEL, "GetImageInfo OUT");
403     return OHOS_IMAGE_RESULT_SUCCESS;
404 }
405 
OHOS_MEDIA_AccessPixels(napi_env env,napi_value value,uint8_t ** addrPtr)406 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_AccessPixels(napi_env env, napi_value value,
407     uint8_t** addrPtr)
408 {
409     HiLog::Debug(LABEL, "AccessPixels IN");
410 
411     PixelMapNapi *pixmapNapi = nullptr;
412     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
413     if (pixmapNapi == nullptr) {
414         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
415         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
416     }
417 
418     std::shared_ptr<PixelMap> *pixelMap = pixmapNapi->GetPixelMap();
419     if ((pixelMap == nullptr) || ((*pixelMap) == nullptr)) {
420         HiLog::Error(LABEL, "pixelMap is nullptr");
421         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
422     }
423 
424     const uint8_t *constPixels = (*pixelMap)->GetPixels();
425     if (constPixels == nullptr) {
426         HiLog::Error(LABEL, "const pixels is nullptr");
427         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
428     }
429 
430     uint8_t *pixels = const_cast<uint8_t*>(constPixels);
431     if (pixels == nullptr) {
432         HiLog::Error(LABEL, "pixels is nullptr");
433         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
434     }
435 
436     pixmapNapi->LockPixelMap();
437 
438     if (addrPtr != nullptr) {
439         *addrPtr = pixels;
440     }
441 
442     HiLog::Debug(LABEL, "AccessPixels OUT");
443     return OHOS_IMAGE_RESULT_SUCCESS;
444 }
445 
OHOS_MEDIA_UnAccessPixels(napi_env env,napi_value value)446 extern "C" __attribute__((visibility("default"))) int32_t OHOS_MEDIA_UnAccessPixels(napi_env env, napi_value value)
447 {
448     HiLog::Debug(LABEL, "UnAccessPixels IN");
449 
450     PixelMapNapi *pixmapNapi = nullptr;
451     napi_unwrap(env, value, reinterpret_cast<void**>(&pixmapNapi));
452     if (pixmapNapi == nullptr) {
453         HiLog::Error(LABEL, "pixmapNapi unwrapped is nullptr");
454         return OHOS_IMAGE_RESULT_BAD_PARAMETER;
455     }
456 
457     pixmapNapi->UnlockPixelMap();
458 
459     HiLog::Debug(LABEL, "UnAccessPixels OUT");
460     return OHOS_IMAGE_RESULT_SUCCESS;
461 }
462 
Constructor(napi_env env,napi_callback_info info)463 napi_value PixelMapNapi::Constructor(napi_env env, napi_callback_info info)
464 {
465     napi_value undefineVar = nullptr;
466     napi_get_undefined(env, &undefineVar);
467 
468     napi_status status;
469     napi_value thisVar = nullptr;
470     napi_get_undefined(env, &thisVar);
471 
472     HiLog::Debug(LABEL, "Constructor IN");
473     IMG_JS_NO_ARGS(env, info, status, thisVar);
474 
475     IMG_NAPI_CHECK_RET(IMG_IS_READY(status, thisVar), undefineVar);
476     std::unique_ptr<PixelMapNapi> pPixelMapNapi = std::make_unique<PixelMapNapi>();
477 
478     IMG_NAPI_CHECK_RET(IMG_NOT_NULL(pPixelMapNapi), undefineVar);
479 
480     pPixelMapNapi->env_ = env;
481     pPixelMapNapi->nativePixelMap_ = sPixelMap_;
482 
483     status = napi_wrap(env, thisVar, reinterpret_cast<void*>(pPixelMapNapi.get()),
484                         PixelMapNapi::Destructor, nullptr, &(pPixelMapNapi->wrapper_));
485     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), undefineVar, HiLog::Error(LABEL, "Failure wrapping js to native napi"));
486 
487     pPixelMapNapi.release();
488     sPixelMap_ = nullptr;
489 
490     return thisVar;
491 }
492 
Destructor(napi_env env,void * nativeObject,void * finalize)493 void PixelMapNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
494 {
495 }
496 
STATIC_EXEC_FUNC(CreatePixelMap)497 STATIC_EXEC_FUNC(CreatePixelMap)
498 {
499     auto context = static_cast<PixelMapAsyncContext*>(data);
500     auto colors = static_cast<uint32_t*>(context->colorsBuffer);
501     auto pixelmap = PixelMap::Create(colors, context->colorsBufferSize, context->opts);
502 
503     context->rPixelMap = std::move(pixelmap);
504 
505     if (IMG_NOT_NULL(context->rPixelMap)) {
506         context->status = SUCCESS;
507     } else {
508         context->status = ERROR;
509     }
510 }
511 
CreatePixelMapComplete(napi_env env,napi_status status,void * data)512 void PixelMapNapi::CreatePixelMapComplete(napi_env env, napi_status status, void *data)
513 {
514     napi_value constructor = nullptr;
515     napi_value result = nullptr;
516 
517     HiLog::Debug(LABEL, "CreatePixelMapComplete IN");
518     auto context = static_cast<PixelMapAsyncContext*>(data);
519 
520     status = napi_get_reference_value(env, sConstructor_, &constructor);
521 
522     if (IMG_IS_OK(status)) {
523         sPixelMap_ = context->rPixelMap;
524         status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
525     }
526 
527     if (!IMG_IS_OK(status)) {
528         context->status = ERROR;
529         HiLog::Error(LABEL, "New instance could not be obtained");
530         napi_get_undefined(env, &result);
531     }
532 
533     CommonCallbackRoutine(env, context, result);
534 }
535 
CreatePixelMap(napi_env env,napi_callback_info info)536 napi_value PixelMapNapi::CreatePixelMap(napi_env env, napi_callback_info info)
537 {
538     napi_value result = nullptr;
539     napi_get_undefined(env, &result);
540 
541     int32_t refCount = 1;
542 
543     napi_status status;
544     napi_value thisVar = nullptr;
545     napi_value argValue[NUM_4] = {0};
546     size_t argCount = NUM_4;
547     HiLog::Debug(LABEL, "CreatePixelMap IN");
548 
549     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
550 
551     // we are static method!
552     // thisVar is nullptr here
553     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
554     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
555 
556     status = napi_get_arraybuffer_info(env, argValue[NUM_0], &(asyncContext->colorsBuffer),
557         &(asyncContext->colorsBufferSize));
558 
559     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "colors mismatch"));
560 
561     IMG_NAPI_CHECK_RET_D(parseInitializationOptions(env, argValue[1], &(asyncContext->opts)),
562         nullptr, HiLog::Error(LABEL, "InitializationOptions mismatch"));
563 
564     if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
565         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
566     }
567 
568     if (asyncContext->callbackRef == nullptr) {
569         napi_create_promise(env, &(asyncContext->deferred), &result);
570     } else {
571         napi_get_undefined(env, &result);
572     }
573 
574     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMap",
575         CreatePixelMapExec, CreatePixelMapComplete, asyncContext, asyncContext->work);
576 
577     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
578         nullptr, HiLog::Error(LABEL, "fail to create async work"));
579     return result;
580 }
581 
CreatePixelMap(napi_env env,std::shared_ptr<PixelMap> pixelmap)582 napi_value PixelMapNapi::CreatePixelMap(napi_env env, std::shared_ptr<PixelMap> pixelmap)
583 {
584     napi_value constructor = nullptr;
585     napi_value result = nullptr;
586     napi_status status;
587 
588     HiLog::Debug(LABEL, "CreatePixelMap IN");
589     status = napi_get_reference_value(env, sConstructor_, &constructor);
590 
591     if (IMG_IS_OK(status)) {
592         sPixelMap_ = pixelmap;
593         status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
594     }
595 
596     if (!IMG_IS_OK(status)) {
597         HiLog::Error(LABEL, "CreatePixelMap | New instance could not be obtained");
598         napi_get_undefined(env, &result);
599     }
600 
601     return result;
602 }
603 
GetIsEditable(napi_env env,napi_callback_info info)604 napi_value PixelMapNapi::GetIsEditable(napi_env env, napi_callback_info info)
605 {
606     napi_value result = nullptr;
607     napi_get_undefined(env, &result);
608 
609     napi_status status;
610     napi_value thisVar = nullptr;
611     size_t argCount = 0;
612     HiLog::Debug(LABEL, "GetIsEditable IN");
613 
614     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
615 
616     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
617 
618     std::unique_ptr<PixelMapNapi> pixelMapNapi = std::make_unique<PixelMapNapi>();
619     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
620 
621     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
622 
623     bool isEditable = pixelMapNapi->nativePixelMap_->IsEditable();
624 
625     napi_get_boolean(env, isEditable, &result);
626 
627     return result;
628 }
629 
ReadPixelsToBuffer(napi_env env,napi_callback_info info)630 napi_value PixelMapNapi::ReadPixelsToBuffer(napi_env env, napi_callback_info info)
631 {
632     napi_value result = nullptr;
633     napi_get_undefined(env, &result);
634 
635     int32_t refCount = 1;
636     napi_status status;
637     napi_value thisVar = nullptr;
638     napi_value argValue[NUM_2] = {0};
639     size_t argCount = NUM_2;
640 
641     HiLog::Debug(LABEL, "ReadPixelsToBuffer IN");
642     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
643 
644     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
645 
646     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
647     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
648 
649     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
650         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
651 
652     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
653 
654     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
655         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
656 
657     status = napi_get_arraybuffer_info(env, argValue[NUM_0],
658             &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
659 
660     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "colors mismatch"));
661 
662     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
663         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
664     }
665 
666     if (asyncContext->callbackRef == nullptr) {
667         napi_create_promise(env, &(asyncContext->deferred), &result);
668     } else {
669         napi_get_undefined(env, &result);
670     }
671 
672     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsToBuffer",
673         [](napi_env env, void *data)
674         {
675             auto context = static_cast<PixelMapAsyncContext*>(data);
676             context->status = context->rPixelMap->ReadPixels(
677                 context->colorsBufferSize, static_cast<uint8_t*>(context->colorsBuffer));
678         }
679         , EmptyResultComplete, asyncContext, asyncContext->work);
680 
681     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
682         nullptr, HiLog::Error(LABEL, "fail to create async work"));
683     return result;
684 
685 }
686 
ReadPixels(napi_env env,napi_callback_info info)687 napi_value PixelMapNapi::ReadPixels(napi_env env, napi_callback_info info)
688 {
689     napi_value result = nullptr;
690     napi_get_undefined(env, &result);
691 
692     int32_t refCount = 1;
693     napi_status status;
694     napi_value thisVar = nullptr;
695     napi_value argValue[NUM_2] = {0};
696     size_t argCount = NUM_2;
697 
698     HiLog::Debug(LABEL, "ReadPixels IN");
699     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
700 
701     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
702 
703     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
704     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
705 
706     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
707         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
708 
709     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
710 
711     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
712         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
713 
714     IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
715         nullptr, HiLog::Error(LABEL, "fail to parse position area"));
716 
717     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
718         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
719     }
720 
721     if (asyncContext->callbackRef == nullptr) {
722         napi_create_promise(env, &(asyncContext->deferred), &result);
723     } else {
724         napi_get_undefined(env, &result);
725     }
726 
727     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixels",
728         [](napi_env env, void *data)
729         {
730             auto context = static_cast<PixelMapAsyncContext*>(data);
731             auto area = context->area;
732             context->status = context->rPixelMap->ReadPixels(
733                 area.size, area.offset, area.stride, area.region, static_cast<uint8_t*>(area.pixels));
734         }, EmptyResultComplete, asyncContext, asyncContext->work);
735 
736     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
737         nullptr, HiLog::Error(LABEL, "fail to create async work"));
738     return result;
739 }
740 
WritePixels(napi_env env,napi_callback_info info)741 napi_value PixelMapNapi::WritePixels(napi_env env, napi_callback_info info)
742 {
743     napi_value result = nullptr;
744     napi_get_undefined(env, &result);
745 
746     int32_t refCount = 1;
747     napi_status status;
748     napi_value thisVar = nullptr;
749     napi_value argValue[NUM_2] = {0};
750     size_t argCount = NUM_2;
751 
752     HiLog::Debug(LABEL, "WritePixels IN");
753     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
754 
755     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
756 
757     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
758     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
759 
760     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
761         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
762 
763     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
764 
765     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
766         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
767 
768     IMG_NAPI_CHECK_RET_D(parsePositionArea(env, argValue[NUM_0], &(asyncContext->area)),
769         nullptr, HiLog::Error(LABEL, "fail to parse position area"));
770 
771     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
772         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
773     }
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, "WritePixels",
782         [](napi_env env, void *data)
783         {
784             auto context = static_cast<PixelMapAsyncContext*>(data);
785             auto area = context->area;
786             context->status = context->rPixelMap->WritePixels(
787                 static_cast<uint8_t*>(area.pixels), area.size, area.offset, area.stride, area.region);
788         }, EmptyResultComplete, asyncContext, asyncContext->work);
789 
790     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
791         nullptr, HiLog::Error(LABEL, "fail to create async work"));
792     return result;
793 
794 }
795 
WriteBufferToPixels(napi_env env,napi_callback_info info)796 napi_value PixelMapNapi::WriteBufferToPixels(napi_env env, napi_callback_info info)
797 {
798     napi_value result = nullptr;
799     napi_get_undefined(env, &result);
800 
801     int32_t refCount = 1;
802     napi_status status;
803     napi_value thisVar = nullptr;
804     napi_value argValue[NUM_2] = {0};
805     size_t argCount = NUM_2;
806 
807     HiLog::Debug(LABEL, "WriteBufferToPixels IN");
808     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
809 
810     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
811 
812     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
813     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
814 
815     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
816         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
817 
818     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
819 
820     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
821         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
822     status = napi_get_arraybuffer_info(env, argValue[NUM_0],
823         &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize));
824 
825     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
826         nullptr, HiLog::Error(LABEL, "fail to get buffer info"));
827 
828     if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
829         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
830     }
831 
832     if (asyncContext->callbackRef == nullptr) {
833         napi_create_promise(env, &(asyncContext->deferred), &result);
834     } else {
835         napi_get_undefined(env, &result);
836     }
837 
838     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "WriteBufferToPixels",
839         [](napi_env env, void *data)
840         {
841             auto context = static_cast<PixelMapAsyncContext*>(data);
842             context->status = context->rPixelMap->WritePixels(static_cast<uint8_t*>(context->colorsBuffer),
843                 context->colorsBufferSize);
844         }, EmptyResultComplete, asyncContext, asyncContext->work);
845 
846     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
847         nullptr, HiLog::Error(LABEL, "fail to create async work"));
848     return result;
849 }
850 
STATIC_COMPLETE_FUNC(GetImageInfo)851 STATIC_COMPLETE_FUNC(GetImageInfo)
852 {
853     HiLog::Debug(LABEL, "[PixelMap]GetImageInfoComplete IN");
854     napi_value result = nullptr;
855     napi_create_object(env, &result);
856     auto context = static_cast<PixelMapAsyncContext*>(data);
857     napi_value size = nullptr;
858     napi_create_object(env, &size);
859     napi_value sizeWith = nullptr;
860     napi_create_int32(env, context->imageInfo.size.width, &sizeWith);
861     napi_set_named_property(env, size, "width", sizeWith);
862     napi_value sizeHeight = nullptr;
863     napi_create_int32(env, context->imageInfo.size.height, &sizeHeight);
864     napi_set_named_property(env, size, "height", sizeHeight);
865     napi_set_named_property(env, result, "size", size);
866     napi_value pixelFormatValue = nullptr;
867     napi_create_int32(env, static_cast<int32_t>(context->imageInfo.pixelFormat), &pixelFormatValue);
868     napi_set_named_property(env, result, "pixelFormat", pixelFormatValue);
869     napi_value colorSpaceValue = nullptr;
870     napi_create_int32(env, static_cast<int32_t>(context->imageInfo.colorSpace), &colorSpaceValue);
871     napi_set_named_property(env, result, "colorSpace", colorSpaceValue);
872     napi_value alphaTypeValue = nullptr;
873     napi_create_int32(env, static_cast<int32_t>(context->imageInfo.alphaType), &alphaTypeValue);
874     napi_set_named_property(env, result, "alphaType", alphaTypeValue);
875     if (!IMG_IS_OK(status)) {
876         context->status = ERROR;
877         HiLog::Error(LABEL, "napi_create_int32 failed!");
878         napi_get_undefined(env, &result);
879     } else {
880         context->status = SUCCESS;
881     }
882     HiLog::Debug(LABEL, "[PixelMap]GetImageInfoComplete OUT");
883     CommonCallbackRoutine(env, context, result);
884 }
GetImageInfo(napi_env env,napi_callback_info info)885 napi_value PixelMapNapi::GetImageInfo(napi_env env, napi_callback_info info)
886 {
887     napi_value result = nullptr;
888     napi_get_undefined(env, &result);
889     int32_t refCount = 1;
890     napi_status status;
891     napi_value thisVar = nullptr;
892     napi_value argValue[NUM_1] = {0};
893     size_t argCount = 1;
894     HiLog::Debug(LABEL, "GetImageInfo IN");
895     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
896     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
897     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
898     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
899     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
900         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
901     asyncContext->rPixelMap = asyncContext->nConstructor->nativePixelMap_;
902     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rPixelMap),
903         nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
904     if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
905         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
906     }
907     if (asyncContext->callbackRef == nullptr) {
908         napi_create_promise(env, &(asyncContext->deferred), &result);
909     } else {
910         napi_get_undefined(env, &result);
911     }
912     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfo",
913         [](napi_env env, void *data)
914         {
915             auto context = static_cast<PixelMapAsyncContext*>(data);
916             context->rPixelMap->GetImageInfo(context->imageInfo);
917             context->status = SUCCESS;
918         }, GetImageInfoComplete, asyncContext, asyncContext->work);
919     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
920         nullptr, HiLog::Error(LABEL, "fail to create async work"));
921     return result;
922 }
923 
GetBytesNumberPerRow(napi_env env,napi_callback_info info)924 napi_value PixelMapNapi::GetBytesNumberPerRow(napi_env env, napi_callback_info info)
925 {
926     napi_value result = nullptr;
927     napi_get_undefined(env, &result);
928 
929     napi_status status;
930     napi_value thisVar = nullptr;
931     size_t argCount = 0;
932 
933     HiLog::Debug(LABEL, "GetBytesNumberPerRow IN");
934     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
935 
936     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
937 
938     std::unique_ptr<PixelMapNapi> pixelMapNapi = std::make_unique<PixelMapNapi>();
939     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
940 
941     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
942     if (pixelMapNapi->nativePixelMap_ != nullptr) {
943         uint32_t rowBytes = pixelMapNapi->nativePixelMap_->GetRowBytes();
944         status = napi_create_int32(env, rowBytes, &result);
945         if (!IMG_IS_OK(status)) {
946             HiLog::Error(LABEL, "napi_create_int32 failed!");
947         }
948     } else {
949         HiLog::Error(LABEL, "native pixelmap is nullptr!");
950     }
951     pixelMapNapi.release();
952     return result;
953 }
954 
GetPixelBytesNumber(napi_env env,napi_callback_info info)955 napi_value PixelMapNapi::GetPixelBytesNumber(napi_env env, napi_callback_info info)
956 {
957     napi_value result = nullptr;
958     napi_get_undefined(env, &result);
959 
960     napi_status status;
961     napi_value thisVar = nullptr;
962     size_t argCount = 0;
963 
964     HiLog::Debug(LABEL, "GetPixelBytesNumber IN");
965     IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
966 
967     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
968 
969     std::unique_ptr<PixelMapNapi> pixelMapNapi = std::make_unique<PixelMapNapi>();
970     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&pixelMapNapi));
971 
972     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, pixelMapNapi), result, HiLog::Error(LABEL, "fail to unwrap context"));
973     if (pixelMapNapi->nativePixelMap_ != nullptr) {
974         uint32_t byteCount = pixelMapNapi->nativePixelMap_->GetByteCount();
975         status = napi_create_int32(env, byteCount, &result);
976         if (!IMG_IS_OK(status)) {
977             HiLog::Error(LABEL, "napi_create_int32 failed!");
978         }
979     } else {
980         HiLog::Error(LABEL, "native pixelmap is nullptr!");
981     }
982     pixelMapNapi.release();
983     return result;
984 }
985 
Release(napi_env env,napi_callback_info info)986 napi_value PixelMapNapi::Release(napi_env env, napi_callback_info info)
987 {
988     napi_value result = nullptr;
989     napi_get_undefined(env, &result);
990 
991     int32_t refCount = 1;
992     napi_status status;
993     napi_value thisVar = nullptr;
994     napi_value argValue[1] = {0};
995     size_t argCount = 1;
996 
997     HiLog::Debug(LABEL, "Release IN");
998     IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
999 
1000     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1001 
1002     std::unique_ptr<PixelMapAsyncContext> asyncContext = std::make_unique<PixelMapAsyncContext>();
1003     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->nConstructor));
1004 
1005     IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor),
1006         nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
1007 
1008     if (argCount == 1 && ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
1009         napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
1010     }
1011 
1012     if (asyncContext->callbackRef == nullptr) {
1013         napi_create_promise(env, &(asyncContext->deferred), &result);
1014     } else {
1015         napi_get_undefined(env, &result);
1016     }
1017 
1018     IMG_CREATE_CREATE_ASYNC_WORK(env, status, "Release",
1019         [](napi_env env, void *data)
1020         {
1021             auto context = static_cast<PixelMapAsyncContext*>(data);
1022             if (context->nConstructor->IsLockPixelMap()) {
1023                 context->status = ERROR;
1024                 return;
1025             } else {
1026                 context->nConstructor->nativePixelMap_= nullptr;
1027                 context->status = SUCCESS;
1028             }
1029         }, EmptyResultComplete, asyncContext, asyncContext->work);
1030 
1031     IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1032         nullptr, HiLog::Error(LABEL, "fail to create async work"));
1033     return result;
1034 }
1035 }  // namespace Media
1036 }  // namespace OHOS
1037