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 "image_source_napi.h"
17 #include <fcntl.h>
18 #include "hilog/log.h"
19 #include "image_napi_utils.h"
20 #include "media_errors.h"
21
22 using OHOS::HiviewDFX::HiLog;
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ImageSourceNapi"};
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 constexpr uint32_t NUM_5 = 5;
31 }
32
33 namespace OHOS {
34 namespace Media {
35 thread_local napi_ref ImageSourceNapi::sConstructor_ = nullptr;
36 std::shared_ptr<ImageSource> ImageSourceNapi::sImgSrc_ = nullptr;
37 std::shared_ptr<IncrementalPixelMap> ImageSourceNapi::sIncPixelMap_ = nullptr;
38 static const std::string CLASS_NAME = "ImageSource";
39 static const std::string FILE_URL_PREFIX = "file://";
40 std::string ImageSourceNapi::filePath_ = "";
41
42 struct ImageSourceAsyncContext {
43 napi_env env;
44 napi_async_work work;
45 napi_deferred deferred;
46 napi_ref callbackRef = nullptr;
47 ImageSourceNapi *constructor_;
48 uint32_t status;
49 std::string pathName;
50 int fdIndex;
51 void* sourceBuffer;
52 size_t sourceBufferSize;
53 std::string keyStr;
54 std::string valueStr;
55 std::string defaultValueStr;
56 int32_t valueInt;
57 int32_t deufltValueInt;
58 void *updataBuffer;
59 size_t updataBufferSize;
60 uint32_t updataBufferOffset = 0;
61 uint32_t updataLength = 0;
62 bool isCompleted = false;
63 bool isSuccess = false;
64 size_t pathNameLength;
65 SourceOptions opts;
66 uint32_t index = 0;
67 ImageInfo imageInfo;
68 DecodeOptions decodeOpts;
69 std::shared_ptr<ImageSource> rImageSource;
70 std::shared_ptr<PixelMap> rPixelMap;
71 };
72
GetStringArgument(napi_env env,napi_value value)73 static std::string GetStringArgument(napi_env env, napi_value value)
74 {
75 std::string strValue = "";
76 size_t bufLength = 0;
77 napi_status status = napi_get_value_string_utf8(env, value, nullptr, NUM_0, &bufLength);
78 if (status == napi_ok && bufLength > NUM_0 && bufLength < PATH_MAX) {
79 char *buffer = (char *)malloc((bufLength + NUM_1) * sizeof(char));
80 if (buffer == nullptr) {
81 HiLog::Error(LABEL, "No memory");
82 return strValue;
83 }
84
85 status = napi_get_value_string_utf8(env, value, buffer, bufLength + NUM_1, &bufLength);
86 if (status == napi_ok) {
87 HiLog::Debug(LABEL, "Get Success");
88 strValue = buffer;
89 }
90 free(buffer);
91 buffer = nullptr;
92 }
93 return strValue;
94 }
95
ImageSourceCallbackRoutine(napi_env env,ImageSourceAsyncContext * & context,const napi_value & valueParam)96 static void ImageSourceCallbackRoutine(napi_env env, ImageSourceAsyncContext* &context, const napi_value &valueParam)
97 {
98 napi_value result[NUM_2] = {0};
99 napi_value retVal;
100 napi_value callback = nullptr;
101
102 napi_get_undefined(env, &result[NUM_0]);
103 napi_get_undefined(env, &result[NUM_1]);
104
105 if (context->status == SUCCESS) {
106 result[NUM_1] = valueParam;
107 }
108
109 if (context->deferred) {
110 if (context->status == SUCCESS) {
111 napi_resolve_deferred(env, context->deferred, result[NUM_1]);
112 } else {
113 napi_reject_deferred(env, context->deferred, result[0]);
114 }
115 } else {
116 HiLog::Debug(LABEL, "call callback function");
117 napi_get_reference_value(env, context->callbackRef, &callback);
118 napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
119 napi_delete_reference(env, context->callbackRef);
120 }
121
122 napi_delete_async_work(env, context->work);
123
124 delete context;
125 context = nullptr;
126 }
127
ImageSourceNapi()128 ImageSourceNapi::ImageSourceNapi()
129 :env_(nullptr), wrapper_(nullptr)
130 {
131
132 }
133
~ImageSourceNapi()134 ImageSourceNapi::~ImageSourceNapi()
135 {
136 if (nativeImgSrc != nullptr) {
137 nativeImgSrc = nullptr;
138 }
139 if (wrapper_ != nullptr) {
140 napi_delete_reference(env_, wrapper_);
141 }
142 isRelease = true;
143 }
144
Init(napi_env env,napi_value exports)145 napi_value ImageSourceNapi::Init(napi_env env, napi_value exports)
146 {
147 napi_property_descriptor properties[] = {
148 DECLARE_NAPI_FUNCTION("getImageInfo", GetImageInfo),
149 DECLARE_NAPI_FUNCTION("modifyImageProperty", ModifyImageProperty),
150 DECLARE_NAPI_FUNCTION("getImageProperty", GetImageProperty),
151 DECLARE_NAPI_FUNCTION("createPixelMap", CreatePixelMap),
152 DECLARE_NAPI_FUNCTION("updateData", UpdateData),
153 DECLARE_NAPI_FUNCTION("release", Release),
154 DECLARE_NAPI_GETTER("supportedFormats", GetSupportedFormats),
155 };
156
157 napi_property_descriptor static_prop[] = {
158 DECLARE_NAPI_STATIC_FUNCTION("createImageSource", CreateImageSource),
159 DECLARE_NAPI_STATIC_FUNCTION("createIncrementalSource", CreateIncrementalSource),
160 };
161
162 napi_value constructor = nullptr;
163 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
164 sizeof(properties) / sizeof(properties[NUM_0]), properties, &constructor);
165
166 if (status != napi_ok) {
167 HiLog::Error(LABEL, "define class fail");
168 return nullptr;
169 }
170
171 status = napi_create_reference(env, constructor, NUM_1, &sConstructor_);
172 if (status != napi_ok) {
173 HiLog::Error(LABEL, "create reference fail");
174 return nullptr;
175 }
176
177 napi_value global = nullptr;
178 status = napi_get_global(env, &global);
179 if (status != napi_ok) {
180 HiLog::Error(LABEL, "Init:get global fail");
181 return nullptr;
182 }
183
184 status = napi_set_named_property(env, global, CLASS_NAME.c_str(), constructor);
185 if (status != napi_ok) {
186 HiLog::Error(LABEL, "Init:set global named property fail");
187 return nullptr;
188 }
189
190 status = napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor);
191 if (status != napi_ok) {
192 HiLog::Error(LABEL, "set named property fail");
193 return nullptr;
194 }
195
196 status = napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[NUM_0]), static_prop);
197 if (status != napi_ok) {
198 HiLog::Error(LABEL, "define properties fail");
199 return nullptr;
200 }
201 HiLog::Debug(LABEL, "Init success");
202 return exports;
203 }
204
Constructor(napi_env env,napi_callback_info info)205 napi_value ImageSourceNapi::Constructor(napi_env env, napi_callback_info info)
206 {
207 napi_value undefineValue = nullptr;
208 napi_get_undefined(env, &undefineValue);
209
210 napi_status status;
211 napi_value thisVar = nullptr;
212
213 status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
214
215 if (status == napi_ok && thisVar != nullptr) {
216 std::unique_ptr<ImageSourceNapi> pImgSrcNapi = std::make_unique<ImageSourceNapi>();
217 if (pImgSrcNapi != nullptr) {
218 pImgSrcNapi->env_ = env;
219 pImgSrcNapi->nativeImgSrc = sImgSrc_;
220 pImgSrcNapi->navIncPixelMap_ = sIncPixelMap_;
221 sIncPixelMap_ = nullptr;
222
223 status = napi_wrap(env, thisVar, reinterpret_cast<void *>(pImgSrcNapi.get()),
224 ImageSourceNapi::Destructor, nullptr, &(pImgSrcNapi->wrapper_));
225 if (status == napi_ok) {
226 pImgSrcNapi.release();
227 return thisVar;
228 } else {
229 HiLog::Error(LABEL, "Failure wrapping js to native napi");
230 }
231 }
232 }
233
234 return undefineValue;
235 }
236
Destructor(napi_env env,void * nativeObject,void * finalize)237 void ImageSourceNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
238 {
239 ImageSourceNapi *pImgSrcNapi = reinterpret_cast<ImageSourceNapi*>(nativeObject);
240 if (pImgSrcNapi != nullptr) {
241 pImgSrcNapi->~ImageSourceNapi();
242 }
243 }
244
GetSupportedFormats(napi_env env,napi_callback_info info)245 napi_value ImageSourceNapi::GetSupportedFormats(napi_env env, napi_callback_info info)
246 {
247 napi_value result = nullptr;
248 napi_get_undefined(env, &result);
249
250 napi_status status;
251 napi_value thisVar = nullptr;
252 size_t argCount = 0;
253 HiLog::Debug(LABEL, "GetSupportedFormats IN");
254
255 IMG_JS_ARGS(env, info, status, argCount, nullptr, thisVar);
256
257 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
258
259 std::unique_ptr<ImageSourceAsyncContext> asyncContext = std::make_unique<ImageSourceAsyncContext>();
260 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->constructor_));
261
262 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->constructor_),
263 nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
264 std::set<std::string> formats;
265 uint32_t ret = asyncContext->constructor_->nativeImgSrc->GetSupportedFormats(formats);
266
267 IMG_NAPI_CHECK_RET_D((ret == SUCCESS),
268 nullptr, HiLog::Error(LABEL, "fail to get supported formats"));
269
270 napi_create_array(env, &result);
271 size_t i = 0;
272 for (const std::string& formatStr: formats) {
273 napi_value format = nullptr;
274 napi_create_string_latin1(env, formatStr.c_str(), formatStr.length(), &format);
275 napi_set_element(env, result, i, format);
276 i++;
277 }
278 return result;
279 }
280
STATIC_COMPLETE_FUNC(GetImageInfo)281 STATIC_COMPLETE_FUNC(GetImageInfo)
282 {
283 HiLog::Debug(LABEL, "[ImageSource]GetImageInfoComplete IN");
284 napi_value result = nullptr;
285 auto context = static_cast<ImageSourceAsyncContext*>(data);
286 if (context->status == SUCCESS) {
287 napi_create_object(env, &result);
288
289 napi_value size = nullptr;
290 napi_create_object(env, &size);
291
292 napi_value sizeWith = nullptr;
293 napi_create_int32(env, context->imageInfo.size.width, &sizeWith);
294 napi_set_named_property(env, size, "width", sizeWith);
295
296 napi_value sizeHeight = nullptr;
297 napi_create_int32(env, context->imageInfo.size.height, &sizeHeight);
298 napi_set_named_property(env, size, "height", sizeHeight);
299
300 napi_set_named_property(env, result, "size", size);
301
302 napi_value pixelFormatValue = nullptr;
303 napi_create_int32(env, static_cast<int32_t>(context->imageInfo.pixelFormat), &pixelFormatValue);
304 napi_set_named_property(env, result, "pixelFormat", pixelFormatValue);
305
306 napi_value colorSpaceValue = nullptr;
307 napi_create_int32(env, static_cast<int32_t>(context->imageInfo.colorSpace), &colorSpaceValue);
308 napi_set_named_property(env, result, "colorSpace", colorSpaceValue);
309
310 napi_value alphaTypeValue = nullptr;
311 napi_create_int32(env, static_cast<int32_t>(context->imageInfo.alphaType), &alphaTypeValue);
312 napi_set_named_property(env, result, "alphaType", alphaTypeValue);
313
314 if (!IMG_IS_OK(status)) {
315 context->status = ERROR;
316 HiLog::Error(LABEL, "napi_create_int32 failed!");
317 napi_get_undefined(env, &result);
318 } else {
319 context->status = SUCCESS;
320 }
321 } else {
322 napi_get_undefined(env, &result);
323 }
324
325 HiLog::Debug(LABEL, "[ImageSource]GetImageInfoComplete OUT");
326 ImageSourceCallbackRoutine(env, context, result);
327 }
328
ParseSize(napi_env env,napi_value root,Size * size)329 static bool ParseSize(napi_env env, napi_value root, Size* size)
330 {
331 if (!GET_INT32_BY_NAME(root, "height", size->height)) {
332 return false;
333 }
334
335 if (!GET_INT32_BY_NAME(root, "width", size->width)) {
336 return false;
337 }
338
339 return true;
340 }
341
ParseRegion(napi_env env,napi_value root,Rect * region)342 static bool ParseRegion(napi_env env, napi_value root, Rect* region)
343 {
344 napi_value tmpValue = nullptr;
345
346 if (!GET_INT32_BY_NAME(root, "x", region->left)) {
347 return false;
348 }
349
350 if (!GET_INT32_BY_NAME(root, "y", region->top)) {
351 return false;
352 }
353
354 if (!GET_NODE_BY_NAME(root, "size", tmpValue)) {
355 return false;
356 }
357
358 if (!GET_INT32_BY_NAME(tmpValue, "height", region->height)) {
359 return false;
360 }
361
362 if (!GET_INT32_BY_NAME(tmpValue, "width", region->width)) {
363 return false;
364 }
365
366 return true;
367 }
368
IsSupportPixelFormat(int32_t val)369 static bool IsSupportPixelFormat(int32_t val)
370 {
371 if (val >= static_cast<int32_t>(PixelFormat::UNKNOWN) &&
372 val <= static_cast<int32_t>(PixelFormat::BGRA_8888)) {
373 return true;
374 }
375
376 return false;
377 }
378
ParsePixlForamt(int32_t val)379 static PixelFormat ParsePixlForamt(int32_t val)
380 {
381 if (val <= static_cast<int32_t>(PixelFormat::CMYK)) {
382 return PixelFormat(val);
383 }
384
385 return PixelFormat::UNKNOWN;
386 }
387
ParseDecodeOptions(napi_env env,napi_value root,DecodeOptions * opts,uint32_t * pIndex)388 static bool ParseDecodeOptions(napi_env env, napi_value root, DecodeOptions* opts, uint32_t* pIndex)
389 {
390 uint32_t tmpNumber = 0;
391 napi_value tmpValue = nullptr;
392
393 if (!ImageNapiUtils::GetUint32ByName(env, root, "index", pIndex)) {
394 HiLog::Debug(LABEL, "no index");
395 }
396
397 if (!GET_UINT32_BY_NAME(root, "sampleSize", opts->sampleSize)) {
398 HiLog::Debug(LABEL, "no sampleSize");
399 }
400
401 if (!GET_UINT32_BY_NAME(root, "rotate", opts->rotateNewDegrees)) {
402 HiLog::Debug(LABEL, "no rotate");
403 } else {
404 if (opts->rotateNewDegrees >= 0 &&
405 opts->rotateNewDegrees <= 360) { // 360 is the maximum rotation angle.
406 opts->rotateDegrees = (float)opts->rotateNewDegrees;
407 } else {
408 HiLog::Debug(LABEL, "Invalid rotate %{public}d", opts->rotateNewDegrees);
409 return false;
410 }
411 }
412
413 if (!GET_BOOL_BY_NAME(root, "editable", opts->editable)) {
414 HiLog::Debug(LABEL, "no editable");
415 }
416
417 if (!GET_NODE_BY_NAME(root, "desiredSize", tmpValue)) {
418 HiLog::Debug(LABEL, "no desiredSize");
419 } else {
420 if (!ParseSize(env, tmpValue, &(opts->desiredSize))) {
421 HiLog::Debug(LABEL, "ParseSize error");
422 }
423 }
424
425 if (!GET_NODE_BY_NAME(root, "desiredRegion", tmpValue)) {
426 HiLog::Debug(LABEL, "no desiredRegion");
427 } else {
428 if (!ParseRegion(env, tmpValue, &(opts->CropRect))) {
429 HiLog::Debug(LABEL, "ParseRegion error");
430 }
431 }
432
433 tmpNumber = 0;
434 if (!GET_UINT32_BY_NAME(root, "desiredPixelFormat", tmpNumber)) {
435 HiLog::Debug(LABEL, "no desiredPixelFormat");
436 } else {
437 if (IsSupportPixelFormat(tmpNumber)) {
438 opts->desiredPixelFormat = ParsePixlForamt(tmpNumber);
439 } else {
440 HiLog::Debug(LABEL, "Invalid desiredPixelFormat %{public}d", tmpNumber);
441 return false;
442 }
443 }
444 return true;
445 }
446
FileUrlToRawPath(const std::string & path)447 static std::string FileUrlToRawPath(const std::string &path)
448 {
449 if (path.size() > FILE_URL_PREFIX.size() &&
450 (path.compare(0, FILE_URL_PREFIX.size(), FILE_URL_PREFIX) == 0)) {
451 return path.substr(FILE_URL_PREFIX.size());
452 }
453 return path;
454 }
455
CreateImageSource(napi_env env,napi_callback_info info)456 napi_value ImageSourceNapi::CreateImageSource(napi_env env, napi_callback_info info)
457 {
458 napi_value result = nullptr;
459 napi_get_undefined(env, &result);
460
461 napi_status status;
462 napi_value thisVar = nullptr;
463 napi_value argValue[NUM_2] = {0};
464 size_t argCount = 2;
465 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
466 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
467
468 std::unique_ptr<ImageSourceAsyncContext> asyncContext = std::make_unique<ImageSourceAsyncContext>();
469 uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
470 SourceOptions opts;
471 std::unique_ptr<ImageSource> imageSource = nullptr;
472 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_string) {
473 size_t bufferSize = 0;
474 status = napi_get_value_string_utf8(env, argValue[NUM_0], nullptr, NUM_0, &bufferSize);
475 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status) && bufferSize > (size_t)0, nullptr,
476 HiLog::Error(LABEL, "fail to get bufferSize"));
477
478 char* buffer = new char[bufferSize + NUM_1] { 0 };
479 status = napi_get_value_string_utf8(env, argValue[NUM_0], buffer,
480 bufferSize + NUM_1, &(asyncContext->pathNameLength));
481 if (!IMG_IS_OK(status)) {
482 delete[] buffer;
483 HiLog::Error(LABEL, "fail to get pathName");
484 return nullptr;
485 }
486
487 asyncContext->pathName = buffer;
488 asyncContext->pathName = FileUrlToRawPath(asyncContext->pathName);
489
490 HiLog::Debug(LABEL, "pathName is [%{public}s]", asyncContext->pathName.c_str());
491 filePath_ = asyncContext->pathName;
492 imageSource = ImageSource::CreateImageSource(asyncContext->pathName, opts, errorCode);
493 } else if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number) {
494 napi_get_value_int32(env, argValue[NUM_0], &asyncContext->fdIndex);
495 HiLog::Debug(LABEL, "CreateImageSource fdIndex is [%{public}d]", asyncContext->fdIndex);
496 imageSource = ImageSource::CreateImageSource(asyncContext->fdIndex, opts, errorCode);
497 } else if (argCount == NUM_1) {
498 status = napi_get_arraybuffer_info(env, argValue[NUM_0],
499 &(asyncContext->sourceBuffer), &(asyncContext->sourceBufferSize));
500 imageSource = ImageSource::CreateImageSource(static_cast<uint8_t *>(asyncContext->sourceBuffer),
501 asyncContext->sourceBufferSize, opts, errorCode);
502 }
503
504 if (errorCode != SUCCESS || imageSource == nullptr) {
505 HiLog::Error(LABEL, "CreateImageSourceExec error");
506 napi_get_undefined(env, &result);
507 return result;
508 }
509 napi_value constructor = nullptr;
510 status = napi_get_reference_value(env, sConstructor_, &constructor);
511 if (IMG_IS_OK(status)) {
512 sImgSrc_ = std::move(imageSource);
513 status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
514 }
515 if (!IMG_IS_OK(status)) {
516 HiLog::Error(LABEL, "New instance could not be obtained");
517 napi_get_undefined(env, &result);
518 }
519 return result;
520 }
521
CreateImageSourceComplete(napi_env env,napi_status status,void * data)522 napi_value ImageSourceNapi::CreateImageSourceComplete(napi_env env, napi_status status, void *data)
523 {
524 napi_value constructor = nullptr;
525 napi_value result = nullptr;
526
527 HiLog::Debug(LABEL, "CreateImageSourceComplete IN");
528 auto context = static_cast<ImageSourceAsyncContext*>(data);
529
530 status = napi_get_reference_value(env, sConstructor_, &constructor);
531
532 if (IMG_IS_OK(status)) {
533 sImgSrc_ = context->rImageSource;
534 status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
535 }
536
537 if (!IMG_IS_OK(status)) {
538 context->status = ERROR;
539 HiLog::Error(LABEL, "New instance could not be obtained");
540 napi_get_undefined(env, &result);
541 }
542 return result;
543 }
544
CreateIncrementalSource(napi_env env,napi_callback_info info)545 napi_value ImageSourceNapi::CreateIncrementalSource(napi_env env, napi_callback_info info)
546 {
547 napi_value result = nullptr;
548 napi_get_undefined(env, &result);
549
550 napi_status status;
551 HiLog::Debug(LABEL, "CreateIncrementalSource IN");
552
553 uint32_t errorCode = 0;
554 IncrementalSourceOptions incOpts;
555 incOpts.incrementalMode = IncrementalMode::INCREMENTAL_DATA;
556 std::unique_ptr<ImageSource> imageSource = ImageSource::CreateIncrementalImageSource(incOpts, errorCode);
557 DecodeOptions decodeOpts;
558 std::unique_ptr<IncrementalPixelMap> incPixelMap = imageSource->CreateIncrementalPixelMap(0, decodeOpts, errorCode);
559 HiLog::Debug(LABEL, "CreateIncrementalImageSource end");
560 if (errorCode != SUCCESS || imageSource == nullptr) {
561 HiLog::Error(LABEL, "CreateIncrementalImageSource error");
562 napi_get_undefined(env, &result);
563 return result;
564 }
565 napi_value constructor = nullptr;
566 status = napi_get_reference_value(env, sConstructor_, &constructor);
567 if (IMG_IS_OK(status)) {
568 sImgSrc_ = std::move(imageSource);
569 sIncPixelMap_ = std::move(incPixelMap);
570 status = napi_new_instance(env, constructor, NUM_0, nullptr, &result);
571 }
572 if (!IMG_IS_OK(status)) {
573 HiLog::Error(LABEL, "New instance could not be obtained");
574 napi_get_undefined(env, &result);
575 }
576 return result;
577 }
578
GetImageInfo(napi_env env,napi_callback_info info)579 napi_value ImageSourceNapi::GetImageInfo(napi_env env, napi_callback_info info)
580 {
581 napi_value result = nullptr;
582 napi_get_undefined(env, &result);
583
584 int32_t refCount = 1;
585 napi_status status;
586 napi_value thisVar = nullptr;
587 napi_value argValue[NUM_2] = {0};
588 size_t argCount = 2;
589 HiLog::Debug(LABEL, "GetImageInfo IN");
590 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
591 HiLog::Debug(LABEL, "GetImageInfo argCount is [%{public}zu]", argCount);
592
593 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
594
595 std::unique_ptr<ImageSourceAsyncContext> asyncContext = std::make_unique<ImageSourceAsyncContext>();
596 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->constructor_));
597
598 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->constructor_),
599 nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
600
601 asyncContext->rImageSource = asyncContext->constructor_->nativeImgSrc;
602
603 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rImageSource),
604 nullptr, HiLog::Error(LABEL, "empty native pixelmap"));
605 HiLog::Debug(LABEL, "GetImageInfo argCount is [%{public}zu]", argCount);
606 if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_function) {
607 HiLog::Debug(LABEL, "GetImageInfo arg0 getType is [%{public}u]", ImageNapiUtils::getType(env, argValue[NUM_0]));
608 napi_create_reference(env, argValue[NUM_0], refCount, &asyncContext->callbackRef);
609 } else if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number) {
610 napi_get_value_uint32(env, argValue[NUM_0], &asyncContext->index);
611 } else if (argCount == NUM_2 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number
612 && ImageNapiUtils::getType(env, argValue[NUM_1]) == napi_function) {
613
614 HiLog::Debug(LABEL, "GetImageInfo arg0 getType is [%{public}u]", ImageNapiUtils::getType(env, argValue[NUM_0]));
615 HiLog::Debug(LABEL, "GetImageInfo arg1 getType is [%{public}u]", ImageNapiUtils::getType(env, argValue[NUM_1]));
616 napi_get_value_uint32(env, argValue[NUM_0], &asyncContext->index);
617 napi_create_reference(env, argValue[NUM_1], refCount, &asyncContext->callbackRef);
618 }
619
620 if (asyncContext->callbackRef == nullptr) {
621 napi_create_promise(env, &(asyncContext->deferred), &result);
622 } else {
623 napi_get_undefined(env, &result);
624 }
625
626 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageInfo",
627 [](napi_env env, void *data) {
628 auto context = static_cast<ImageSourceAsyncContext*>(data);
629
630 int index = (context->index >= NUM_0) ? context->index : NUM_0;
631 context->status = context->rImageSource->GetImageInfo(index, context->imageInfo);
632
633 }, GetImageInfoComplete, asyncContext, asyncContext->work);
634
635 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
636 nullptr, HiLog::Error(LABEL, "fail to create async work"));
637 return result;
638 }
639
CreatePixelMapExecute(napi_env env,void * data)640 static void CreatePixelMapExecute(napi_env env, void *data)
641 {
642 HiLog::Debug(LABEL, "CreatePixelMapExecute IN");
643 uint32_t errorCode = 0;
644 auto context = static_cast<ImageSourceAsyncContext*>(data);
645 if (context == nullptr) {
646 HiLog::Error(LABEL, "empty context");
647 return;
648 }
649
650 if (context->rImageSource == nullptr) {
651 HiLog::Error(LABEL, "empty context rImageSource");
652 return;
653 }
654
655 if (context->constructor_ != nullptr) {
656 auto incPixelMap = context->constructor_->GetIncrementalPixelMap();
657 if (incPixelMap != nullptr) {
658 HiLog::Info(LABEL, "Get Incremental PixelMap!!!");
659 context->rPixelMap = incPixelMap;
660 }
661 } else {
662 HiLog::Info(LABEL, "Get Incremental PixelMap!!!");
663 }
664 if (context->rPixelMap == nullptr) {
665 int index = (context->index >= NUM_0) ? context->index : NUM_0;
666 context->rPixelMap = context->rImageSource->CreatePixelMap(index, context->decodeOpts, errorCode);
667 }
668 if (context->rPixelMap == nullptr) {
669 HiLog::Error(LABEL, "empty context rPixelMap");
670 }
671 HiLog::Error(LABEL, "CreatePixelMap out");
672 if (IMG_NOT_NULL(context->rPixelMap)) {
673 context->status = SUCCESS;
674 } else {
675 context->status = ERROR;
676 }
677 HiLog::Debug(LABEL, "CreatePixelMapExecute OUT");
678 }
679
CreatePixelMapComplete(napi_env env,napi_status status,void * data)680 static void CreatePixelMapComplete(napi_env env, napi_status status, void *data)
681 {
682 HiLog::Debug(LABEL, "CreatePixelMapComplete IN");
683 napi_value result = nullptr;
684 napi_create_object(env, &result);
685
686 auto context = static_cast<ImageSourceAsyncContext*>(data);
687
688 result = PixelMapNapi::CreatePixelMap(env, context->rPixelMap);
689 HiLog::Debug(LABEL, "CreatePixelMapComplete OUT");
690 ImageSourceCallbackRoutine(env, context, result);
691 }
692
CreatePixelMap(napi_env env,napi_callback_info info)693 napi_value ImageSourceNapi::CreatePixelMap(napi_env env, napi_callback_info info)
694 {
695 napi_value result = nullptr;
696 napi_get_undefined(env, &result);
697
698 int32_t refCount = 1;
699 napi_status status;
700 napi_value thisVar = nullptr;
701 napi_value argValue[NUM_2] = {0};
702 size_t argCount = NUM_2;
703 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
704 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, thisVar), nullptr, HiLog::Error(LABEL, "fail to get thisVar"));
705 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
706
707 std::unique_ptr<ImageSourceAsyncContext> asyncContext = std::make_unique<ImageSourceAsyncContext>();
708
709 std::shared_ptr<ImageSourceNapi> imageSourceNapi = std::make_unique<ImageSourceNapi>();
710 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&imageSourceNapi));
711 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, imageSourceNapi),
712 nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
713 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, imageSourceNapi->nativeImgSrc),
714 nullptr, HiLog::Error(LABEL, "fail to unwrap nativeImgSrc"));
715 asyncContext->constructor_ = imageSourceNapi.get();
716 asyncContext->rImageSource = imageSourceNapi->nativeImgSrc;
717 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rImageSource),
718 nullptr, HiLog::Error(LABEL, "empty native rImageSource"));
719
720 if (argCount == NUM_0) {
721 HiLog::Debug(LABEL, "CreatePixelMap with no arg");
722 } else if (argCount == NUM_1 || argCount == NUM_2) {
723 if (ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_object) {
724 IMG_NAPI_CHECK_RET_D(ParseDecodeOptions(env, argValue[NUM_0],
725 &(asyncContext->decodeOpts),
726 &asyncContext->index),
727 nullptr, HiLog::Error(LABEL, "DecodeOptions mismatch"));
728 }
729 if (ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
730 napi_create_reference(env, argValue[argCount - 1], refCount, &asyncContext->callbackRef);
731 }
732 } else {
733 HiLog::Error(LABEL, "argCount missmatch");
734 return result;
735 }
736 if (asyncContext->callbackRef == nullptr) {
737 napi_create_promise(env, &(asyncContext->deferred), &result);
738 } else {
739 napi_get_undefined(env, &result);
740 }
741
742 ImageNapiUtils::HicheckerReport();
743 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMap", CreatePixelMapExecute,
744 CreatePixelMapComplete, asyncContext, asyncContext->work);
745
746 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
747 nullptr, HiLog::Error(LABEL, "fail to create async work"));
748 return result;
749 }
750
ParsePropertyOptions(napi_env env,napi_value root,ImageSourceAsyncContext * context)751 static bool ParsePropertyOptions(napi_env env, napi_value root, ImageSourceAsyncContext* context)
752 {
753 napi_value tmpValue = nullptr;
754 if (!GET_UINT32_BY_NAME(root, "index", context->index)) {
755 HiLog::Debug(LABEL, "no index");
756 return false;
757 }
758 if (!GET_NODE_BY_NAME(root, "defaultValue", tmpValue)) {
759 HiLog::Debug(LABEL, "no defaultValue");
760 } else {
761 if (tmpValue != nullptr) {
762 context->defaultValueStr = GetStringArgument(env, tmpValue);
763 }
764 }
765 return true;
766 }
767
ModifyImagePropertyComplete(napi_env env,napi_status status,ImageSourceAsyncContext * context)768 static void ModifyImagePropertyComplete(napi_env env, napi_status status, ImageSourceAsyncContext *context)
769 {
770 HiLog::Debug(LABEL, "ModifyPropertyComplete IN");
771
772 if (context == nullptr) {
773 HiLog::Error(LABEL, "context is nullptr");
774 return;
775 }
776 napi_value result = nullptr;
777 napi_get_undefined(env, &result);
778
779 HiLog::Debug(LABEL, "ModifyPropertyComplete OUT");
780 ImageSourceCallbackRoutine(env, context, result);
781 }
782
GetImagePropertyComplete(napi_env env,napi_status status,ImageSourceAsyncContext * context)783 static void GetImagePropertyComplete(napi_env env, napi_status status, ImageSourceAsyncContext *context)
784 {
785 HiLog::Debug(LABEL, "GetImagePropertyComplete IN");
786
787 if (context == nullptr) {
788 HiLog::Error(LABEL, "context is nullptr");
789 return;
790 }
791 napi_value result = nullptr;
792 napi_create_object(env, &result);
793
794 if (context->status == SUCCESS) {
795 napi_create_string_utf8(env, context->valueStr.c_str(), context->valueStr.length(), &result);
796 } else {
797 napi_create_string_utf8(env, context->defaultValueStr.c_str(), context->defaultValueStr.length(), &result);
798 context->status = SUCCESS;
799 }
800 HiLog::Debug(LABEL, "GetImagePropertyComplete OUT");
801 ImageSourceCallbackRoutine(env, context, result);
802 }
803
UnwrapContext(napi_env env,napi_callback_info info)804 static std::unique_ptr<ImageSourceAsyncContext> UnwrapContext(napi_env env, napi_callback_info info)
805 {
806 int32_t refCount = 1;
807 napi_status status;
808 napi_value thisVar = nullptr;
809 napi_value argValue[NUM_3] = {0};
810 size_t argCount = NUM_3;
811 HiLog::Debug(LABEL, "GetImageProperty UnwrapContext");
812 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
813 HiLog::Debug(LABEL, "GetImageProperty argCount is [%{public}zu]", argCount);
814
815 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
816
817 std::unique_ptr<ImageSourceAsyncContext> context = std::make_unique<ImageSourceAsyncContext>();
818 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&context->constructor_));
819
820 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, context->constructor_),
821 nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
822
823 context->rImageSource = context->constructor_->nativeImgSrc;
824
825 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, context->rImageSource),
826 nullptr, HiLog::Error(LABEL, "empty native rImageSource"));
827
828 if (argCount < NUM_1 || argCount > NUM_3) {
829 HiLog::Error(LABEL, "argCount missmatch");
830 return nullptr;
831 }
832 if (ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_string) {
833 context->keyStr = GetStringArgument(env, argValue[NUM_0]);
834 } else {
835 HiLog::Error(LABEL, "arg 0 type missmatch");
836 return nullptr;
837 }
838 if (argCount == NUM_2 || argCount == NUM_3) {
839 if (ImageNapiUtils::getType(env, argValue[NUM_1]) == napi_object) {
840 IMG_NAPI_CHECK_RET_D(ParsePropertyOptions(env, argValue[NUM_1], context.get()),
841 nullptr, HiLog::Error(LABEL, "PropertyOptions mismatch"));
842 }
843 if (ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
844 napi_create_reference(env, argValue[argCount - 1], refCount, &context->callbackRef);
845 }
846 }
847 return context;
848 }
849
UnwrapContextForModify(napi_env env,napi_callback_info info)850 static std::unique_ptr<ImageSourceAsyncContext> UnwrapContextForModify(napi_env env,
851 napi_callback_info info)
852 {
853 int32_t refCount = 1;
854 napi_status status;
855 napi_value thisVar = nullptr;
856 napi_value argValue[NUM_4] = {0};
857 size_t argCount = NUM_4;
858 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
859 HiLog::Debug(LABEL, "UnwrapContextForModify argCount is [%{public}zu]", argCount);
860
861 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
862
863 std::unique_ptr<ImageSourceAsyncContext> context = std::make_unique<ImageSourceAsyncContext>();
864 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&context->constructor_));
865
866 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, context->constructor_),
867 nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
868
869 context->rImageSource = context->constructor_->nativeImgSrc;
870
871 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, context->rImageSource),
872 nullptr, HiLog::Error(LABEL, "empty native rImageSource"));
873 if (argCount < NUM_1 || argCount > NUM_4) {
874 HiLog::Error(LABEL, "argCount missmatch");
875 return nullptr;
876 }
877 if (ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_string) {
878 context->keyStr = GetStringArgument(env, argValue[NUM_0]);
879 } else {
880 HiLog::Error(LABEL, "arg 0 type missmatch");
881 return nullptr;
882 }
883 if (ImageNapiUtils::getType(env, argValue[NUM_1]) == napi_string) {
884 context->valueStr = GetStringArgument(env, argValue[NUM_1]);
885 } else {
886 HiLog::Error(LABEL, "arg 1 type missmatch");
887 return nullptr;
888 }
889 if (argCount == NUM_3 || argCount == NUM_4) {
890 if (ImageNapiUtils::getType(env, argValue[NUM_2]) == napi_object) {
891 IMG_NAPI_CHECK_RET_D(ParsePropertyOptions(env, argValue[NUM_2], context.get()),
892 nullptr, HiLog::Error(LABEL, "PropertyOptions mismatch"));
893 }
894 if (ImageNapiUtils::getType(env, argValue[argCount - 1]) == napi_function) {
895 napi_create_reference(env, argValue[argCount - 1], refCount, &context->callbackRef);
896 }
897 }
898 context->pathName = ImageSourceNapi::filePath_;
899 return context;
900 }
901
ModifyImageProperty(napi_env env,napi_callback_info info)902 napi_value ImageSourceNapi::ModifyImageProperty(napi_env env, napi_callback_info info)
903 {
904 napi_value result = nullptr;
905 napi_get_undefined(env, &result);
906
907 napi_status status;
908 HiLog::Debug(LABEL, "ModifyImageProperty IN");
909 std::unique_ptr<ImageSourceAsyncContext> asyncContext = UnwrapContextForModify(env, info);
910 if (asyncContext == nullptr) {
911 HiLog::Error(LABEL, "async context unwrap failed");
912 return result;
913 }
914
915 if (asyncContext->callbackRef == nullptr) {
916 napi_create_promise(env, &(asyncContext->deferred), &result);
917 } else {
918 napi_get_undefined(env, &result);
919 }
920
921 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ModifyImageProperty",
922 [](napi_env env, void *data)
923 {
924 auto context = static_cast<ImageSourceAsyncContext*>(data);
925 context->status = context->rImageSource->ModifyImageProperty(context->index,
926 context->keyStr, context->valueStr, context->pathName);
927 },
928 reinterpret_cast<napi_async_complete_callback>(ModifyImagePropertyComplete),
929 asyncContext,
930 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
GetImageProperty(napi_env env,napi_callback_info info)937 napi_value ImageSourceNapi::GetImageProperty(napi_env env, napi_callback_info info)
938 {
939 napi_value result = nullptr;
940 napi_get_undefined(env, &result);
941
942 napi_status status;
943 HiLog::Debug(LABEL, "GetImageProperty IN");
944 std::unique_ptr<ImageSourceAsyncContext> asyncContext = UnwrapContext(env, info);
945 if (asyncContext == nullptr) {
946 HiLog::Error(LABEL, "async context unwrap failed");
947 return result;
948 }
949
950 if (asyncContext->callbackRef == nullptr) {
951 napi_create_promise(env, &(asyncContext->deferred), &result);
952 } else {
953 napi_get_undefined(env, &result);
954 }
955
956 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetImageProperty",
957 [](napi_env env, void *data)
958 {
959 auto context = static_cast<ImageSourceAsyncContext*>(data);
960 context->status = context->rImageSource->GetImagePropertyString(context->index,
961 context->keyStr,
962 context->valueStr);
963 },
964 reinterpret_cast<napi_async_complete_callback>(GetImagePropertyComplete),
965 asyncContext,
966 asyncContext->work);
967
968 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
969 nullptr, HiLog::Error(LABEL, "fail to create async work"));
970 return result;
971 }
972
UpdateDataExecute(napi_env env,void * data)973 static void UpdateDataExecute(napi_env env, void *data)
974 {
975 auto context = static_cast<ImageSourceAsyncContext*>(data);
976 uint8_t *buffer = static_cast<uint8_t*>(context->updataBuffer);
977 if (context->updataBufferOffset < context->updataBufferSize) {
978 buffer = buffer + context->updataBufferOffset;
979 }
980
981 uint32_t lastSize = context->updataBufferSize - context->updataBufferOffset;
982 uint32_t size = context->updataLength < lastSize ? context->updataLength : lastSize;
983
984 uint32_t res = context->rImageSource->UpdateData(buffer, size,
985 context->isCompleted);
986 context->isSuccess = res == 0;
987 if (context->isSuccess && context->constructor_ != nullptr) {
988 auto incPixelMap = context->constructor_->GetIncrementalPixelMap();
989 if (incPixelMap != nullptr) {
990 uint8_t decodeProgress = 0;
991 uint32_t err = incPixelMap->PromoteDecoding(decodeProgress);
992 if (!(err == SUCCESS || (err == ERR_IMAGE_SOURCE_DATA_INCOMPLETE && !context->isCompleted))) {
993 HiLog::Error(LABEL, "UpdateData PromoteDecoding error");
994 context->isSuccess = false;
995 }
996 if (context->isCompleted) {
997 incPixelMap->DetachFromDecoding();
998 }
999 }
1000 }
1001 }
1002
UpdateDataComplete(napi_env env,napi_status status,void * data)1003 static void UpdateDataComplete(napi_env env, napi_status status, void *data)
1004 {
1005 HiLog::Debug(LABEL, "UpdateDataComplete IN");
1006 napi_value result = nullptr;
1007 napi_create_object(env, &result);
1008
1009 auto context = static_cast<ImageSourceAsyncContext*>(data);
1010
1011 napi_get_boolean(env, context->isSuccess, &result);
1012 HiLog::Debug(LABEL, "UpdateDataComplete OUT");
1013 ImageSourceCallbackRoutine(env, context, result);
1014 }
1015
isNapiTypedArray(napi_env env,napi_value val)1016 static bool isNapiTypedArray(napi_env env, napi_value val)
1017 {
1018 bool res = false;
1019 napi_is_typedarray(env, val, &res);
1020 HiLog::Debug(LABEL, "isNapiTypedArray %{public}d", res);
1021 return res;
1022 }
1023
UpdateData(napi_env env,napi_callback_info info)1024 napi_value ImageSourceNapi::UpdateData(napi_env env, napi_callback_info info)
1025 {
1026 napi_value result = nullptr;
1027 napi_get_undefined(env, &result);
1028
1029 int32_t refCount = 1;
1030 napi_status status;
1031 napi_value thisVar = nullptr;
1032 napi_value argValue[NUM_5] = {0};
1033 size_t argCount = 5;
1034 HiLog::Debug(LABEL, "UpdateData IN");
1035 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1036 HiLog::Debug(LABEL, "UpdateData argCount is [%{public}zu]", argCount);
1037
1038 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1039
1040 std::unique_ptr<ImageSourceAsyncContext> asyncContext = std::make_unique<ImageSourceAsyncContext>();
1041 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->constructor_));
1042
1043 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->constructor_),
1044 nullptr, HiLog::Error(LABEL, "fail to unwrap context"));
1045
1046 asyncContext->rImageSource = asyncContext->constructor_->nativeImgSrc;
1047
1048 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->rImageSource),
1049 nullptr, HiLog::Error(LABEL, "empty native rImageSource"));
1050 HiLog::Error(LABEL, "UpdateData argCount %{public}d ", argCount);
1051 if (argCount > NUM_0 && isNapiTypedArray(env, argValue[NUM_0])) {
1052 HiLog::Error(LABEL, "UpdateData napi_get_arraybuffer_info ");
1053 napi_typedarray_type type;
1054 napi_value arraybuffer;
1055 size_t offset;
1056 status = napi_get_typedarray_info(env, argValue[NUM_0], &type,
1057 &(asyncContext->updataBufferSize), &(asyncContext->updataBuffer),
1058 &arraybuffer, &offset);
1059 }
1060
1061 if (argCount >= NUM_2 && ImageNapiUtils::getType(env, argValue[NUM_1]) == napi_boolean) {
1062 status = napi_get_value_bool(env, argValue[NUM_1], &(asyncContext->isCompleted));
1063 }
1064
1065 if (argCount >= NUM_3 && ImageNapiUtils::getType(env, argValue[NUM_2]) == napi_number) {
1066 asyncContext->updataBufferOffset = 0;
1067 status = napi_get_value_uint32(env, argValue[NUM_2], &(asyncContext->updataBufferOffset));
1068 HiLog::Debug(LABEL, "asyncContext->updataBufferOffset is [%{public}u]", asyncContext->updataBufferOffset);
1069 }
1070
1071 if (argCount >= NUM_4 && ImageNapiUtils::getType(env, argValue[NUM_3]) == napi_number) {
1072 asyncContext->updataLength = 0;
1073 status = napi_get_value_uint32(env, argValue[NUM_3], &(asyncContext->updataLength));
1074 HiLog::Debug(LABEL, "asyncContext->updataLength is [%{public}u]", asyncContext->updataLength);
1075 }
1076
1077 if (argCount == NUM_5 && ImageNapiUtils::getType(env, argValue[NUM_4]) == napi_function) {
1078 napi_create_reference(env, argValue[NUM_4], refCount, &asyncContext->callbackRef);
1079 }
1080
1081 if (argCount == NUM_3 && ImageNapiUtils::getType(env, argValue[NUM_2]) == napi_function) {
1082 napi_create_reference(env, argValue[NUM_2], refCount, &asyncContext->callbackRef);
1083 }
1084
1085 if (asyncContext->callbackRef == nullptr) {
1086 napi_create_promise(env, &(asyncContext->deferred), &result);
1087 } else {
1088 napi_get_undefined(env, &result);
1089 }
1090
1091 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "UpdateData",
1092 UpdateDataExecute, UpdateDataComplete, asyncContext, asyncContext->work);
1093
1094 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status),
1095 nullptr, HiLog::Error(LABEL, "fail to create async work"));
1096 return result;
1097 }
1098
ReleaseComplete(napi_env env,napi_status status,void * data)1099 static void ReleaseComplete(napi_env env, napi_status status, void *data)
1100 {
1101 HiLog::Debug(LABEL, "ReleaseComplete IN");
1102 napi_value result = nullptr;
1103 napi_get_undefined(env, &result);
1104
1105 auto context = static_cast<ImageSourceAsyncContext*>(data);
1106 context->constructor_->~ImageSourceNapi();
1107 HiLog::Debug(LABEL, "ReleaseComplete OUT");
1108 ImageSourceCallbackRoutine(env, context, result);
1109 }
1110
Release(napi_env env,napi_callback_info info)1111 napi_value ImageSourceNapi::Release(napi_env env, napi_callback_info info)
1112 {
1113 HiLog::Debug(LABEL, "Release enter");
1114 napi_value result = nullptr;
1115 napi_get_undefined(env, &result);
1116
1117 int32_t refCount = 1;
1118 napi_status status;
1119 napi_value thisVar = nullptr;
1120 napi_value argValue[NUM_1] = {0};
1121 size_t argCount = 1;
1122
1123 IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
1124 HiLog::Debug(LABEL, "Release argCount is [%{public}zu]", argCount);
1125 IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), result, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
1126
1127 std::unique_ptr<ImageSourceAsyncContext> asyncContext = std::make_unique<ImageSourceAsyncContext>();
1128 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->constructor_));
1129
1130 IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->constructor_), result,
1131 HiLog::Error(LABEL, "fail to unwrap context"));
1132
1133 HiLog::Debug(LABEL, "Release argCount is [%{public}zu]", argCount);
1134 if (argCount == 1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_function) {
1135 napi_create_reference(env, argValue[NUM_0], refCount, &asyncContext->callbackRef);
1136 }
1137
1138 if (asyncContext->callbackRef == nullptr) {
1139 napi_create_promise(env, &(asyncContext->deferred), &result);
1140 }
1141
1142 IMG_CREATE_CREATE_ASYNC_WORK(env, status, "Release",
1143 [](napi_env env, void *data) {}, ReleaseComplete, asyncContext, asyncContext->work);
1144 HiLog::Debug(LABEL, "Release exit");
1145 return result;
1146 }
1147 } // namespace Media
1148 } // namespace OHOS
1149