• 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 "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