1 /*
2  * Copyright (C) 2023 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_mdk_kits.h"
17 #include <map>
18 #include "image_log.h"
19 #include "media_errors.h"
20 #include "securec.h"
21 #include "image_dfx.h"
22 
23 #undef LOG_DOMAIN
24 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
25 
26 #undef LOG_TAG
27 #define LOG_TAG "ImageSourceMdk"
28 
29 namespace {
30     constexpr size_t SIZE_ZERO = 0;
31     constexpr int32_t INVALID_FD = -1;
32     constexpr uint32_t DEFAULT_INDEX = 0;
33     constexpr uint32_t INVALID_SAMPLE_SIZE = 0;
34     constexpr int8_t INT8_TRUE = 1;
35 }
36 
37 namespace OHOS {
38 namespace Media {
39 using ImageSourceNapiFunc = int32_t (*)(struct ImageSourceArgs* args);
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
GetNativeImageSource(struct ImageSourceArgs * args)44 static ImageSource* GetNativeImageSource(struct ImageSourceArgs* args)
45 {
46     if (args == nullptr || args->napi == nullptr || args->napi->nativeImgSrc == nullptr) {
47         return nullptr;
48     }
49     return args->napi->nativeImgSrc.get();
50 }
51 
ParseImageSourceOps(SourceOptions & opts,struct OhosImageSourceOps * ops)52 static void ParseImageSourceOps(SourceOptions &opts, struct OhosImageSourceOps* ops)
53 {
54     opts.baseDensity = ops->density;
55     opts.pixelFormat = static_cast<PixelFormat>(ops->pixelFormat);
56     opts.size.width = ops->size.width;
57     opts.size.height = ops->size.height;
58 }
59 
ParseDecodingOps(DecodeOptions & decOps,struct OhosImageDecodingOps * ops)60 static void ParseDecodingOps(DecodeOptions &decOps, struct OhosImageDecodingOps* ops)
61 {
62     if (ops->sampleSize != INVALID_SAMPLE_SIZE) {
63         decOps.sampleSize = ops->sampleSize;
64     }
65     decOps.rotateNewDegrees = ops->rotate;
66     decOps.editable = (ops->editable == INT8_TRUE);
67     decOps.desiredSize.width = ops->size.width;
68     decOps.desiredSize.height = ops->size.height;
69     decOps.desiredRegion.left = ops->region.x;
70     decOps.desiredRegion.top = ops->region.y;
71     decOps.desiredRegion.width = ops->region.width;
72     decOps.desiredRegion.height = ops->region.height;
73     if (ops->pixelFormat < static_cast<int32_t>(PixelFormat::EXTERNAL_MAX)) {
74         decOps.desiredPixelFormat = PixelFormat(ops->pixelFormat);
75     }
76     decOps.fitDensity = ops->fitDensity;
77 }
78 
ParseImageSourceInfo(struct OhosImageSourceInfo * source,ImageInfo & info)79 static void ParseImageSourceInfo(struct OhosImageSourceInfo* source, ImageInfo &info)
80 {
81     source->alphaType = static_cast<int32_t>(info.alphaType);
82     source->colorSpace = static_cast<int32_t>(info.colorSpace);
83     source->density = info.baseDensity;
84     source->pixelFormat = static_cast<int32_t>(info.pixelFormat);
85     source->size.width = info.size.width;
86     source->size.height = info.size.height;
87 }
88 
UrlToPath(const std::string & path)89 static std::string UrlToPath(const std::string &path)
90 {
91     const std::string filePrefix = "file://";
92     if (path.size() > filePrefix.size() &&
93         (path.compare(0, filePrefix.size(), filePrefix) == 0)) {
94         return path.substr(filePrefix.size());
95     }
96     return path;
97 }
98 
UnwrapNativeObject(napi_env env,napi_value value)99 static ImageSourceNapi* UnwrapNativeObject(napi_env env, napi_value value)
100 {
101     napi_valuetype valueType;
102     napi_typeof(env, value, &valueType);
103     if (valueType != napi_object) {
104         IMAGE_LOGE("UnwrapNativeObject value not a object");
105         return nullptr;
106     }
107     std::unique_ptr<ImageSourceNapi> napi = nullptr;
108     napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&napi));
109     if ((status == napi_ok) && napi != nullptr) {
110         return napi.release();
111     }
112     IMAGE_LOGE("UnwrapNativeObject unwrap error");
113     return nullptr;
114 }
115 
ImageSourceNativeCreate(struct OhosImageSource * source,struct OhosImageSourceOps * ops,std::shared_ptr<ImageSource> & result,ImageResource & resource)116 static int32_t ImageSourceNativeCreate(struct OhosImageSource* source,
117     struct OhosImageSourceOps* ops, std::shared_ptr<ImageSource> &result, ImageResource &resource)
118 {
119     if (source == nullptr) {
120         IMAGE_LOGE("ImageSourceNativeCreate source nullptr");
121         return IMAGE_RESULT_BAD_PARAMETER;
122     }
123     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
124     SourceOptions opts;
125     if (ops != nullptr) {
126         ParseImageSourceOps(opts, ops);
127     }
128     std::unique_ptr<ImageSource> nativeImageSource = nullptr;
129     if (source->uri != nullptr && source->uriSize != SIZE_ZERO) {
130         IMAGE_LOGD("ImageSourceNativeCreate by path");
131         std::string url(source->uri, source->uriSize);
132         IMAGE_LOGD("ImageSourceNativeCreate by path %{public}s", url.c_str());
133         auto path = UrlToPath(url);
134         nativeImageSource = ImageSource::CreateImageSource(path, opts, errorCode);
135         resource.type = ImageResourceType::IMAGE_RESOURCE_PATH;
136         resource.path = path;
137     } else if (source->fd != INVALID_FD) {
138         IMAGE_LOGD("ImageSourceNativeCreate by fd");
139         nativeImageSource = ImageSource::CreateImageSource(source->fd, opts, errorCode);
140         resource.type = ImageResourceType::IMAGE_RESOURCE_FD;
141         resource.fd = source->fd;
142     } else if (source->buffer != nullptr && source->bufferSize != SIZE_ZERO) {
143         IMAGE_LOGD("ImageSourceNativeCreate by buffer");
144         nativeImageSource = ImageSource::CreateImageSource(source->buffer,
145             source->bufferSize, opts, errorCode);
146         resource.type = ImageResourceType::IMAGE_RESOURCE_BUFFER;
147         resource.buffer = source->buffer;
148         resource.bufferSize = source->bufferSize;
149     }
150     if (nativeImageSource != nullptr) {
151         result = std::move(nativeImageSource);
152         IMAGE_LOGD("ImageSourceNativeCreate success");
153         return IMAGE_RESULT_SUCCESS;
154     }
155     IMAGE_LOGE("ImageSourceNativeCreate no match source");
156     return IMAGE_RESULT_BAD_PARAMETER;
157 }
158 
ImageSourceCreateNapi(napi_env env,napi_value * res,std::shared_ptr<ImageSource> imageSource,std::shared_ptr<IncrementalPixelMap> incrementalPixelMap,ImageResource * resource)159 static int32_t ImageSourceCreateNapi(napi_env env, napi_value* res,
160     std::shared_ptr<ImageSource> imageSource,
161     std::shared_ptr<IncrementalPixelMap> incrementalPixelMap, ImageResource* resource)
162 {
163     if (ImageSourceNapi::CreateImageSourceNapi(env, res) != SUCCESS) {
164         IMAGE_LOGE("ImageSourceCreateNapi napi create failed");
165         return IMAGE_RESULT_BAD_PARAMETER;
166     }
167     auto napi = UnwrapNativeObject(env, *(res));
168     if (napi == nullptr) {
169         IMAGE_LOGE("ImageSourceCreateNapi napi unwrap check failed");
170         return IMAGE_RESULT_BAD_PARAMETER;
171     }
172 
173     if (imageSource != nullptr) {
174         napi->SetNativeImageSource(imageSource);
175     }
176     if (incrementalPixelMap != nullptr) {
177         napi->SetIncrementalPixelMap(incrementalPixelMap);
178     }
179     if (resource != nullptr) {
180         napi->SetImageResource(*resource);
181     }
182     IMAGE_LOGD("ImageSourceCreateNapi success");
183     return IMAGE_RESULT_SUCCESS;
184 }
185 
ImageSourceNapiCreate(struct ImageSourceArgs * args)186 static int32_t ImageSourceNapiCreate(struct ImageSourceArgs* args)
187 {
188     if (args == nullptr || args->inEnv == nullptr) {
189         return IMAGE_RESULT_BAD_PARAMETER;
190     }
191     std::shared_ptr<ImageSource> imageSource = nullptr;
192     ImageResource resource;
193     ImageSourceNativeCreate(args->source, args->sourceOps, imageSource, resource);
194     if (imageSource == nullptr) {
195         IMAGE_LOGE("ImageSourceNapiCreate native create failed");
196         return IMAGE_RESULT_BAD_PARAMETER;
197     }
198     if (ImageSourceCreateNapi(args->inEnv, args->outVal, imageSource, nullptr, &resource) != SUCCESS) {
199         IMAGE_LOGE("ImageSourceNapiCreate napi create failed");
200         args->outVal = nullptr;
201         return IMAGE_RESULT_BAD_PARAMETER;
202     }
203     IMAGE_LOGD("ImageSourceNapiCreate success");
204     return IMAGE_RESULT_SUCCESS;
205 }
206 
ImageSourceNapiCreateFromUri(struct ImageSourceArgs * args)207 static int32_t ImageSourceNapiCreateFromUri(struct ImageSourceArgs* args)
208 {
209     if (args == nullptr || args->inEnv == nullptr || args->uri.empty()) {
210         return IMAGE_RESULT_BAD_PARAMETER;
211     }
212     SourceOptions opts;
213     if (args->sourceOps != nullptr) {
214         ParseImageSourceOps(opts, args->sourceOps);
215     }
216     IMAGE_LOGD("ImageSourceNapiCreateFromUri by path %{public}s", args->uri.c_str());
217     auto path = UrlToPath(args->uri);
218     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
219     std::unique_ptr<ImageSource> nativeImageSource = ImageSource::CreateImageSource(path, opts, errorCode);
220     if (nativeImageSource == nullptr) {
221         IMAGE_LOGD("ImageSourceNapiCreateFromUri create failed:%{public}d", errorCode);
222         return IMAGE_RESULT_BAD_PARAMETER;
223     }
224     ImageResource resource;
225     resource.type = ImageResourceType::IMAGE_RESOURCE_PATH;
226     resource.path = path;
227     std::shared_ptr<ImageSource> imageSource = std::move(nativeImageSource);
228     if (imageSource == nullptr) {
229         IMAGE_LOGE("ImageSourceNapiCreateFromUri native create failed");
230         return IMAGE_RESULT_BAD_PARAMETER;
231     }
232     if (ImageSourceCreateNapi(args->inEnv, args->outVal, imageSource, nullptr, &resource) != SUCCESS) {
233         IMAGE_LOGE("ImageSourceNapiCreateFromUri napi create failed");
234         args->outVal = nullptr;
235         return IMAGE_RESULT_BAD_PARAMETER;
236     }
237     IMAGE_LOGD("ImageSourceNapiCreateFromUri success");
238     return IMAGE_RESULT_SUCCESS;
239 }
240 
ImageSourceNapiCreateFromFd(struct ImageSourceArgs * args)241 static int32_t ImageSourceNapiCreateFromFd(struct ImageSourceArgs* args)
242 {
243     if (args == nullptr || args->inEnv == nullptr || args->fd == INVALID_FD) {
244         return IMAGE_RESULT_BAD_PARAMETER;
245     }
246     SourceOptions opts;
247     if (args->sourceOps != nullptr) {
248         ParseImageSourceOps(opts, args->sourceOps);
249     }
250     IMAGE_LOGD("ImageSourceNapiCreateFromFd");
251     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
252     std::unique_ptr<ImageSource> nativeImageSource = ImageSource::CreateImageSource(args->fd, opts, errorCode);
253     if (nativeImageSource == nullptr) {
254         IMAGE_LOGD("ImageSourceNapiCreateFromFd create failed:%{public}d", errorCode);
255         return IMAGE_RESULT_BAD_PARAMETER;
256     }
257     ImageResource resource;
258     resource.type = ImageResourceType::IMAGE_RESOURCE_FD;
259     resource.fd = args->fd;
260     std::shared_ptr<ImageSource> imageSource = std::move(nativeImageSource);
261     if (imageSource == nullptr) {
262         IMAGE_LOGE("ImageSourceNapiCreateFromFd native create failed");
263         return IMAGE_RESULT_BAD_PARAMETER;
264     }
265     if (ImageSourceCreateNapi(args->inEnv, args->outVal, imageSource, nullptr, &resource) != SUCCESS) {
266         IMAGE_LOGE("ImageSourceNapiCreateFromFd napi create failed");
267         args->outVal = nullptr;
268         return IMAGE_RESULT_BAD_PARAMETER;
269     }
270     IMAGE_LOGD("ImageSourceNapiCreateFromFd success");
271     return IMAGE_RESULT_SUCCESS;
272 }
273 
ImageSourceNapiCreateFromData(struct ImageSourceArgs * args)274 static int32_t ImageSourceNapiCreateFromData(struct ImageSourceArgs* args)
275 {
276     if (args == nullptr || args->inEnv == nullptr ||
277         args->dataArray.data == nullptr || args->dataArray.dataSize == SIZE_ZERO) {
278         return IMAGE_RESULT_BAD_PARAMETER;
279     }
280     SourceOptions opts;
281     if (args->sourceOps != nullptr) {
282         ParseImageSourceOps(opts, args->sourceOps);
283     }
284     IMAGE_LOGD("ImageSourceNapiCreateFromData");
285     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
286     std::unique_ptr<ImageSource> nativeImageSource = ImageSource::CreateImageSource(
287         args->dataArray.data, args->dataArray.dataSize, opts, errorCode);
288     if (nativeImageSource == nullptr) {
289         IMAGE_LOGD("ImageSourceNapiCreateFromData create failed:%{public}d", errorCode);
290         return IMAGE_RESULT_BAD_PARAMETER;
291     }
292     ImageResource resource;
293     resource.type = ImageResourceType::IMAGE_RESOURCE_BUFFER;
294     resource.buffer = args->dataArray.data;
295     resource.bufferSize = args->dataArray.dataSize;
296     std::shared_ptr<ImageSource> imageSource = std::move(nativeImageSource);
297     if (imageSource == nullptr) {
298         IMAGE_LOGE("ImageSourceNapiCreateFromData native create failed");
299         return IMAGE_RESULT_BAD_PARAMETER;
300     }
301     if (ImageSourceCreateNapi(args->inEnv, args->outVal, imageSource, nullptr, &resource) != SUCCESS) {
302         IMAGE_LOGE("ImageSourceNapiCreateFromData napi create failed");
303         args->outVal = nullptr;
304         return IMAGE_RESULT_BAD_PARAMETER;
305     }
306     IMAGE_LOGD("ImageSourceNapiCreateFromData success");
307     return IMAGE_RESULT_SUCCESS;
308 }
309 
isValidRawFile(RawFileDescriptor & rawFile)310 static bool isValidRawFile(RawFileDescriptor &rawFile)
311 {
312     return rawFile.fd != INVALID_FD && rawFile.start >= static_cast<long>(SIZE_ZERO) &&
313         rawFile.length > static_cast<long>(SIZE_ZERO);
314 }
315 
ImageSourceNapiCreateFromRawFile(struct ImageSourceArgs * args)316 static int32_t ImageSourceNapiCreateFromRawFile(struct ImageSourceArgs* args)
317 {
318     if (args == nullptr || args->inEnv == nullptr || !isValidRawFile(args->rawFile)) {
319         return IMAGE_RESULT_BAD_PARAMETER;
320     }
321     SourceOptions opts;
322     if (args->sourceOps != nullptr) {
323         ParseImageSourceOps(opts, args->sourceOps);
324     }
325     RawFileDescriptor rawFile = args->rawFile;
326     IMAGE_LOGD("ImageSourceNapiCreateFromRawFile");
327     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
328     int32_t rawFileLength = rawFile.start + rawFile.length;
329     std::unique_ptr<ImageSource> nativeImageSource = ImageSource::CreateImageSource(
330         rawFile.fd, rawFile.start, rawFileLength, opts, errorCode);
331     if (nativeImageSource == nullptr) {
332         IMAGE_LOGD("ImageSourceNapiCreateFromRawFile create failed:%{public}d", errorCode);
333         return IMAGE_RESULT_BAD_PARAMETER;
334     }
335     ImageResource resource;
336     resource.type = ImageResourceType::IMAGE_RESOURCE_RAW_FILE;
337     resource.fd = rawFile.fd;
338     resource.fileStart = rawFile.start;
339     resource.fileLength = rawFileLength;
340     std::shared_ptr<ImageSource> imageSource = std::move(nativeImageSource);
341     if (imageSource == nullptr) {
342         IMAGE_LOGE("ImageSourceNapiCreateFromRawFile native create failed");
343         return IMAGE_RESULT_BAD_PARAMETER;
344     }
345     if (ImageSourceCreateNapi(args->inEnv, args->outVal, imageSource, nullptr, &resource) != SUCCESS) {
346         IMAGE_LOGE("ImageSourceNapiCreateFromRawFile napi create failed");
347         args->outVal = nullptr;
348         return IMAGE_RESULT_BAD_PARAMETER;
349     }
350     IMAGE_LOGD("ImageSourceNapiCreateFromRawFile success");
351     return IMAGE_RESULT_SUCCESS;
352 }
353 
ImageSourceNapiCreateIncremental(struct ImageSourceArgs * args)354 static int32_t ImageSourceNapiCreateIncremental(struct ImageSourceArgs* args)
355 {
356     if (args == nullptr || args->inEnv == nullptr) {
357         IMAGE_LOGE("ImageSourceNapiCreateIncremental args or env is nullptr");
358         return IMAGE_RESULT_BAD_PARAMETER;
359     }
360     IncrementalSourceOptions incOpts;
361     if (args->sourceOps != nullptr) {
362         IMAGE_LOGD("ImageSourceNapiCreate ParseImageSourceOps");
363         ParseImageSourceOps(incOpts.sourceOptions, args->sourceOps);
364     }
365     incOpts.incrementalMode = IncrementalMode::INCREMENTAL_DATA;
366     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
367     std::unique_ptr<ImageSource> imageSource = ImageSource::CreateIncrementalImageSource(incOpts, errorCode);
368     if (imageSource == nullptr) {
369         IMAGE_LOGE("ImageSourceNapiCreateIncremental native imagesource failed");
370         return IMAGE_RESULT_BAD_PARAMETER;
371     }
372     if (args->dataArray.data != nullptr && args->dataArray.dataSize > SIZE_ZERO) {
373         IMAGE_LOGD("ImageSourceNapiCreateIncremental update dataArray");
374         imageSource->UpdateData(args->dataArray.data, args->dataArray.dataSize, false);
375     }
376     DecodeOptions decodeOpts;
377     uint32_t index = DEFAULT_INDEX;
378     if (args->decodingOps != nullptr) {
379         ParseDecodingOps(decodeOpts, args->decodingOps);
380         index = args->decodingOps->index;
381     }
382     std::unique_ptr<IncrementalPixelMap> incPixelMap = imageSource->CreateIncrementalPixelMap(
383         index, decodeOpts, errorCode);
384     if (incPixelMap == nullptr) {
385         IMAGE_LOGE("ImageSourceNapiCreateIncremental native incremental pixelmap failed");
386         return IMAGE_RESULT_BAD_PARAMETER;
387     }
388     if (ImageSourceCreateNapi(args->inEnv, args->outVal,
389         std::move(imageSource), std::move(incPixelMap), nullptr) != SUCCESS) {
390         IMAGE_LOGE("ImageSourceNapiCreateIncremental napi create failed");
391         args->outVal = nullptr;
392         return IMAGE_RESULT_BAD_PARAMETER;
393     }
394     IMAGE_LOGD("ImageSourceNapiCreateIncremental success");
395     return IMAGE_RESULT_SUCCESS;
396 }
397 
ImageSourceNapiGetSupportedFormats(struct ImageSourceArgs * args)398 static int32_t ImageSourceNapiGetSupportedFormats(struct ImageSourceArgs* args)
399 {
400     if (args == nullptr) {
401         IMAGE_LOGE("ImageSourceNapiGetSupportedFormats args is nullptr");
402         return IMAGE_RESULT_BAD_PARAMETER;
403     }
404     auto formats = args->outFormats;
405     if (formats == nullptr) {
406         IMAGE_LOGE("ImageSourceNapiGetSupportedFormats args or napi is nullptr");
407         return IMAGE_RESULT_BAD_PARAMETER;
408     }
409     std::set<std::string> formatSet;
410     uint32_t errorCode = ImageSource::GetSupportedFormats(formatSet);
411     if (errorCode != SUCCESS) {
412         IMAGE_LOGE("ImageSourceNapiGetSupportedFormats native failed");
413         return IMAGE_RESULT_BAD_PARAMETER;
414     }
415 
416     size_t formatCount = formatSet.size();
417     if (formats->supportedFormatList == nullptr) {
418         formats->size = formatCount;
419         IMAGE_LOGD("ImageSourceNapiGetSupportedFormats get count only Success");
420         return IMAGE_RESULT_SUCCESS;
421     } else {
422         formatCount = formats->size;
423     }
424 
425     auto formatList = formats->supportedFormatList;
426     size_t i = 0;
427     for (const std::string& formatStr: formatSet) {
428         if (i >= formatCount) {
429             break;
430         }
431         if (formatList[i] == nullptr || formatList[i]->format == nullptr) {
432             IMAGE_LOGD("ImageSourceNapiGetSupportedFormats nullptr format out buffer");
433             return IMAGE_RESULT_BAD_PARAMETER;
434         }
435         if (EOK != memcpy_s(formatList[i]->format, formatList[i]->size, formatStr.c_str(), formatStr.size())) {
436             IMAGE_LOGE("ImageSourceNapiGetSupportedFormats failed, memcpy error");
437             return IMAGE_RESULT_BAD_PARAMETER;
438         }
439         if (formatList[i]->size > formatStr.size()) {
440             formatList[i]->size = formatStr.size();
441         }
442         i++;
443     }
444     IMAGE_LOGD("ImageSourceNapiGetSupportedFormats Success");
445     return IMAGE_RESULT_SUCCESS;
446 }
447 
ImageSourceNapiUnwrap(struct ImageSourceArgs * args)448 static int32_t ImageSourceNapiUnwrap(struct ImageSourceArgs* args)
449 {
450     if (args == nullptr || args->inEnv == nullptr || args->inVal == nullptr) {
451         IMAGE_LOGE("ImageSourceNapiUnwrap args or env is nullptr");
452         return IMAGE_RESULT_BAD_PARAMETER;
453     }
454     args->napi = UnwrapNativeObject(args->inEnv, args->inVal);
455     if (args->napi == nullptr) {
456         IMAGE_LOGE("ImageSourceNapiUnwrap UnwrapNativeObject failed");
457         return IMAGE_RESULT_BAD_PARAMETER;
458     }
459     return IMAGE_RESULT_SUCCESS;
460 }
461 
ImageSourceNapiCreatePixelmap(struct ImageSourceArgs * args)462 static int32_t ImageSourceNapiCreatePixelmap(struct ImageSourceArgs* args)
463 {
464     auto native = GetNativeImageSource(args);
465     if (native == nullptr || args->inEnv == nullptr) {
466         IMAGE_LOGE("ImageSourceNapiCreatePixelmap args or napi is nullptr");
467         return IMAGE_RESULT_BAD_PARAMETER;
468     }
469     std::shared_ptr<PixelMap> nativePixelMap = args->napi->GetIncrementalPixelMap();
470     if (nativePixelMap == nullptr) {
471         DecodeOptions decOps;
472         uint32_t index = DEFAULT_INDEX;
473         uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
474         if (args->decodingOps != nullptr) {
475             ParseDecodingOps(decOps, args->decodingOps);
476             index = args->decodingOps->index;
477         }
478         decOps.desiredDynamicRange = DecodeDynamicRange::SDR;
479         IMAGE_LOGD("ImageSourceNapiCreatePixelmap CreatePixelMapEx");
480         decOps.invokeType = C_INTERFACE;
481         auto tmpPixelmap = native->CreatePixelMapEx(index, decOps, errorCode);
482         if (tmpPixelmap != nullptr) {
483             nativePixelMap = std::move(tmpPixelmap);
484         }
485     }
486     if (nativePixelMap == nullptr) {
487         IMAGE_LOGE("ImageSourceNapiCreatePixelmap native failed");
488         return IMAGE_RESULT_BAD_PARAMETER;
489     }
490     *(args->outVal) = PixelMapNapi::CreatePixelMap(args->inEnv, nativePixelMap);
491     if (*(args->outVal) == nullptr) {
492         IMAGE_LOGE("ImageSourceNapiCreatePixelmap create pixelmap failed");
493         return IMAGE_RESULT_BAD_PARAMETER;
494     }
495     IMAGE_LOGD("ImageSourceNapiCreatePixelmap Success");
496     return IMAGE_RESULT_SUCCESS;
497 }
498 
ImageSourceNapiCreatePixelmapList(struct ImageSourceArgs * args)499 static int32_t ImageSourceNapiCreatePixelmapList(struct ImageSourceArgs* args)
500 {
501     auto native = GetNativeImageSource(args);
502     if (native == nullptr || args->inEnv == nullptr) {
503         IMAGE_LOGE("ImageSourceNapiCreatePixelmapList args or napi is nullptr");
504         return IMAGE_RESULT_BAD_PARAMETER;
505     }
506     DecodeOptions decOps;
507     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
508     if (args->decodingOps != nullptr) {
509         ParseDecodingOps(decOps, args->decodingOps);
510     }
511     decOps.desiredDynamicRange = DecodeDynamicRange::SDR;
512     decOps.invokeType = C_INTERFACE;
513     auto pixelMapList = native->CreatePixelMapList(decOps, errorCode);
514     if (pixelMapList == nullptr) {
515         IMAGE_LOGE("ImageSourceNapiCreatePixelmapList CreatePixelMapList failed");
516         return IMAGE_RESULT_BAD_PARAMETER;
517     }
518     napi_create_array(args->inEnv, args->outVal);
519     size_t i = DEFAULT_INDEX;
520     for (auto &item : *pixelMapList) {
521         auto napiPixelMap = PixelMapNapi::CreatePixelMap(args->inEnv, std::move(item));
522         napi_set_element(args->inEnv, *(args->outVal), i, napiPixelMap);
523         i++;
524     }
525     IMAGE_LOGD("ImageSourceNapiCreatePixelmapList Success");
526     return IMAGE_RESULT_SUCCESS;
527 }
528 
ImageSourceNapiGetDelayTime(struct ImageSourceArgs * args)529 static int32_t ImageSourceNapiGetDelayTime(struct ImageSourceArgs* args) __attribute__((no_sanitize("cfi")))
530 {
531     auto native = GetNativeImageSource(args);
532     if (native == nullptr || args->outDelayTimes == nullptr) {
533         IMAGE_LOGE("ImageSourceNapiGetDelayTime native image or out is nullptr");
534         return IMAGE_RESULT_BAD_PARAMETER;
535     }
536     auto outDelayTimes = args->outDelayTimes;
537     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
538     auto delayTimes = native->GetDelayTime(errorCode);
539     if (delayTimes == nullptr) {
540         IMAGE_LOGE("ImageSourceNapiGetDelayTime native failed");
541         return IMAGE_RESULT_BAD_PARAMETER;
542     }
543     size_t actCount = (*delayTimes).size();
544     if (outDelayTimes->delayTimeList == nullptr) {
545         IMAGE_LOGE("ImageSourceNapiGetDelayTime get times count only");
546         outDelayTimes->size = actCount;
547         return IMAGE_RESULT_SUCCESS;
548     }
549     if (actCount > outDelayTimes->size) {
550         actCount = outDelayTimes->size;
551     }
552     for (size_t i = SIZE_ZERO; i < actCount; i++) {
553         outDelayTimes->delayTimeList[i] = (*delayTimes)[i];
554     }
555     IMAGE_LOGD("ImageSourceNapiGetDelayTime Success");
556     return IMAGE_RESULT_SUCCESS;
557 }
558 
ImageSourceNapiGetFrameCount(struct ImageSourceArgs * args)559 static int32_t ImageSourceNapiGetFrameCount(struct ImageSourceArgs* args)
560 {
561     auto native = GetNativeImageSource(args);
562     if (native == nullptr || args->outUint32 == nullptr) {
563         IMAGE_LOGE("ImageSourceNapiGetFrameCount native image or out is nullptr");
564         return IMAGE_RESULT_BAD_PARAMETER;
565     }
566     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
567     *(args->outUint32) = native->GetFrameCount(errorCode);
568     if (errorCode != SUCCESS) {
569         IMAGE_LOGE("ImageSourceNapiGetFrameCount native failed");
570         return IMAGE_RESULT_BAD_PARAMETER;
571     }
572     IMAGE_LOGD("ImageSourceNapiGetFrameCount Success");
573     return IMAGE_RESULT_SUCCESS;
574 }
575 
ImageSourceNapiGetImageInfo(struct ImageSourceArgs * args)576 static int32_t ImageSourceNapiGetImageInfo(struct ImageSourceArgs* args)
577 {
578     auto native = GetNativeImageSource(args);
579     if (native == nullptr) {
580         IMAGE_LOGE("ImageSourceNapiGetImageInfo native image is nullptr");
581         return IMAGE_RESULT_BAD_PARAMETER;
582     }
583     auto imageSourceInfo = args->outInfo;
584     if (imageSourceInfo == nullptr) {
585         IMAGE_LOGE("ImageSourceNapiGetImageInfo image info is nullptr");
586         return IMAGE_RESULT_BAD_PARAMETER;
587     }
588     ImageInfo imageInfo;
589     uint32_t errorCode = native->GetImageInfo(args->inInt32, imageInfo);
590     if (errorCode != SUCCESS) {
591         IMAGE_LOGE("ImageSourceNapiGetImageInfo native failed");
592         return IMAGE_RESULT_BAD_PARAMETER;
593     }
594     ParseImageSourceInfo(imageSourceInfo, imageInfo);
595     IMAGE_LOGD("ImageSourceNapiGetImageInfo Success");
596     return IMAGE_RESULT_SUCCESS;
597 }
598 
ImageSourceNapiGetImageProperty(struct ImageSourceArgs * args)599 static int32_t ImageSourceNapiGetImageProperty(
600     struct ImageSourceArgs* args) __attribute__((no_sanitize("cfi")))
601 {
602     auto native = GetNativeImageSource(args);
603     if (native == nullptr) {
604         IMAGE_LOGE("ImageSourceNapiGetImageProperty native image is nullptr");
605         return IMAGE_RESULT_BAD_PARAMETER;
606     }
607     auto propertyKey = args->inPropertyKey;
608     auto propertyVal = args->propertyVal;
609     if (propertyKey == nullptr || propertyKey->value == nullptr || propertyKey->size == SIZE_ZERO) {
610         IMAGE_LOGE("ImageSourceNapiGetImageProperty key is empty");
611         return IMAGE_RESULT_BAD_PARAMETER;
612     }
613     if (propertyVal == nullptr) {
614         IMAGE_LOGE("ImageSourceNapiGetImageProperty out val is nullptr");
615         return IMAGE_RESULT_BAD_PARAMETER;
616     }
617     std::string key(propertyKey->value, propertyKey->size);
618     std::string val;
619     uint32_t errorCode = native->GetImagePropertyString(DEFAULT_INDEX, key, val);
620     if (errorCode != SUCCESS || val.empty()) {
621         IMAGE_LOGE("ImageSourceNapiGetImageProperty native failed");
622         return IMAGE_RESULT_BAD_PARAMETER;
623     }
624     if (propertyVal->value == nullptr) {
625         IMAGE_LOGD("ImageSourceNapiGetImageProperty return size only");
626         propertyVal->size = val.size();
627         return IMAGE_RESULT_SUCCESS;
628     }
629     if (EOK != memcpy_s(propertyVal->value, propertyVal->size, val.c_str(), val.size())) {
630         IMAGE_LOGE("ImageSourceNapiGetSupportedFormats failed, memcpy error");
631         return IMAGE_RESULT_BAD_PARAMETER;
632     }
633     if (propertyVal->size > val.size()) {
634         propertyVal->size = val.size();
635     }
636     IMAGE_LOGD("ImageSourceNapiGetImageProperty Success");
637     return IMAGE_RESULT_SUCCESS;
638 }
639 
NativePropertyModify(ImageSource * native,ImageResource & imageResource,std::string & key,std::string & val)640 static int32_t NativePropertyModify(ImageSource* native, ImageResource &imageResource,
641     std::string &key, std::string &val)
642 {
643     auto type = imageResource.type;
644     uint32_t errorCode = SUCCESS;
645     if (type == ImageResourceType::IMAGE_RESOURCE_INVAILD) {
646         IMAGE_LOGE("NativePropertyModify resource is invaild");
647         return IMAGE_RESULT_BAD_PARAMETER;
648     } else if (type == ImageResourceType::IMAGE_RESOURCE_FD && imageResource.fd != INVALID_FD) {
649         IMAGE_LOGD("NativePropertyModify fd resource");
650         errorCode = native->ModifyImageProperty(DEFAULT_INDEX, key, val, imageResource.fd);
651     } else if (type == ImageResourceType::IMAGE_RESOURCE_PATH && !imageResource.path.empty()) {
652         IMAGE_LOGD("NativePropertyModify path resource");
653         errorCode = native->ModifyImageProperty(DEFAULT_INDEX, key, val, imageResource.path);
654     } else if (type == ImageResourceType::IMAGE_RESOURCE_BUFFER &&
655         imageResource.buffer != nullptr && imageResource.bufferSize > SIZE_ZERO) {
656         IMAGE_LOGD("NativePropertyModify buffer resource");
657         errorCode = native->ModifyImageProperty(DEFAULT_INDEX, key, val,
658             imageResource.buffer, imageResource.bufferSize);
659     } else {
660         IMAGE_LOGE("NativePropertyModify %{public}d resource error", type);
661         return IMAGE_RESULT_BAD_PARAMETER;
662     }
663     if (errorCode == SUCCESS) {
664         IMAGE_LOGD("NativePropertyModify Success");
665         return IMAGE_RESULT_SUCCESS;
666     }
667     IMAGE_LOGE("NativePropertyModify native failed");
668     return IMAGE_RESULT_BAD_PARAMETER;
669 }
670 
ImageSourceNapiModifyImageProperty(struct ImageSourceArgs * args)671 static int32_t ImageSourceNapiModifyImageProperty(struct ImageSourceArgs* args)
672 {
673     auto native = GetNativeImageSource(args);
674     if (native == nullptr) {
675         IMAGE_LOGE("ImageSourceNapiModifyImageProperty native image is nullptr");
676         return IMAGE_RESULT_BAD_PARAMETER;
677     }
678     auto propertyKey = args->inPropertyKey;
679     auto propertyVal = args->propertyVal;
680     if (propertyKey == nullptr || propertyKey->value == nullptr || propertyKey->size == SIZE_ZERO) {
681         IMAGE_LOGE("ImageSourceNapiModifyImageProperty key is empty");
682         return IMAGE_RESULT_BAD_PARAMETER;
683     }
684     if (propertyVal == nullptr || propertyVal->value == nullptr || propertyVal->size == SIZE_ZERO) {
685         IMAGE_LOGE("ImageSourceNapiModifyImageProperty val is nullptr");
686         return IMAGE_RESULT_BAD_PARAMETER;
687     }
688     std::string key(propertyKey->value, propertyKey->size);
689     std::string val(propertyVal->value, propertyVal->size);
690     auto imageResource = args->napi->GetImageResource();
691     auto res = NativePropertyModify(native, imageResource, key, val);
692     return res;
693 }
694 
ProcessIncrementalPixelMap(struct ImageSourceArgs * args,bool completed)695 static int32_t ProcessIncrementalPixelMap(struct ImageSourceArgs* args, bool completed)
696 {
697     auto incPixelMap = args->napi->GetIncrementalPixelMap();
698     if (incPixelMap == nullptr) {
699         IMAGE_LOGE("ProcessIncrementalPixelMap incremental pixelmap is nullptr");
700         return IMAGE_RESULT_BAD_PARAMETER;
701     }
702     uint8_t tmpProgress = 0;
703     uint32_t errCode = incPixelMap->PromoteDecoding(tmpProgress);
704     if (completed) {
705         incPixelMap->DetachFromDecoding();
706     }
707     if (errCode != SUCCESS || (errCode == ERR_IMAGE_SOURCE_DATA_INCOMPLETE && !completed)) {
708         IMAGE_LOGE("ProcessIncrementalPixelMap promote decoding failed");
709         return IMAGE_RESULT_BAD_PARAMETER;
710     }
711     return IMAGE_RESULT_SUCCESS;
712 }
713 
MathMin(uint32_t a,uint32_t b)714 static uint32_t MathMin(uint32_t a, uint32_t b)
715 {
716     if (a < b) {
717         return a;
718     }
719     return b;
720 }
721 
ImageSourceNapiUpdateData(struct ImageSourceArgs * args)722 static int32_t ImageSourceNapiUpdateData(struct ImageSourceArgs* args)
723 {
724     auto native = GetNativeImageSource(args);
725     if (native == nullptr) {
726         IMAGE_LOGE("ImageSourceNapiUpdateData native image is nullptr");
727         return IMAGE_RESULT_BAD_PARAMETER;
728     }
729     auto data = args->inUpdateData;
730     if (data == nullptr || data->buffer == nullptr || data->bufferSize == SIZE_ZERO ||
731         data->offset >= data->bufferSize) {
732         IMAGE_LOGE("ImageSourceNapiUpdateData update data is empty");
733         return IMAGE_RESULT_BAD_PARAMETER;
734     }
735     uint32_t actSize = MathMin((data->bufferSize - data->offset), data->updateLength);
736     bool completed = data->isCompleted == INT8_TRUE;
737     uint32_t errCode = native->UpdateData((data->buffer + data->offset), actSize, completed);
738     if (errCode != SUCCESS) {
739         IMAGE_LOGE("ImageSourceNapiUpdateData update native failed");
740         return IMAGE_RESULT_BAD_PARAMETER;
741     }
742     return ProcessIncrementalPixelMap(args, completed);
743 }
744 
745 static const std::map<int32_t, ImageSourceNapiFunc> g_Functions = {
746     {ENV_FUNC_IMAGE_SOURCE_CREATE, ImageSourceNapiCreate},
747     {ENV_FUNC_IMAGE_SOURCE_CREATE_FROM_URI, ImageSourceNapiCreateFromUri},
748     {ENV_FUNC_IMAGE_SOURCE_CREATE_FROM_FD, ImageSourceNapiCreateFromFd},
749     {ENV_FUNC_IMAGE_SOURCE_CREATE_FROM_DATA, ImageSourceNapiCreateFromData},
750     {ENV_FUNC_IMAGE_SOURCE_CREATE_FROM_RAW_FILE, ImageSourceNapiCreateFromRawFile},
751     {ENV_FUNC_IMAGE_SOURCE_CREATE_INCREMENTAL, ImageSourceNapiCreateIncremental},
752     {ENV_FUNC_IMAGE_SOURCE_UNWRAP, ImageSourceNapiUnwrap},
753     {STA_FUNC_IMAGE_SOURCE_GET_SUPPORTED_FORMATS, ImageSourceNapiGetSupportedFormats},
754     {CTX_FUNC_IMAGE_SOURCE_CREATE_PIXELMAP, ImageSourceNapiCreatePixelmap},
755     {CTX_FUNC_IMAGE_SOURCE_CREATE_PIXELMAP_LIST, ImageSourceNapiCreatePixelmapList},
756     {CTX_FUNC_IMAGE_SOURCE_GET_DELAY_TIME, ImageSourceNapiGetDelayTime},
757     {CTX_FUNC_IMAGE_SOURCE_GET_FRAME_COUNT, ImageSourceNapiGetFrameCount},
758     {CTX_FUNC_IMAGE_SOURCE_GET_IMAGE_INFO, ImageSourceNapiGetImageInfo},
759     {CTX_FUNC_IMAGE_SOURCE_GET_IMAGE_PROPERTY, ImageSourceNapiGetImageProperty},
760     {CTX_FUNC_IMAGE_SOURCE_MODIFY_IMAGE_PROPERTY, ImageSourceNapiModifyImageProperty},
761     {CTX_FUNC_IMAGE_SOURCE_UPDATE_DATA, ImageSourceNapiUpdateData}
762 };
763 
764 MIDK_EXPORT
ImageSourceNativeCall(int32_t mode,struct ImageSourceArgs * args)765 int32_t ImageSourceNativeCall(int32_t mode, struct ImageSourceArgs* args)
766 {
767     auto funcSearch = g_Functions.find(mode);
768     if (funcSearch == g_Functions.end()) {
769         return IMAGE_RESULT_BAD_PARAMETER;
770     }
771     return funcSearch->second(args);
772 }
773 #ifdef __cplusplus
774 };
775 #endif
776 }  // namespace Media
777 }  // namespace OHOS