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