• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hilog/log.h"
19 #include "media_errors.h"
20 #include "securec.h"
21 
22 namespace {
23     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ImageSourceMdk"};
24     constexpr size_t SIZE_ZERO = 0;
25     constexpr int32_t INVALID_FD = -1;
26     constexpr uint32_t DEFAULT_INDEX = 0;
27     constexpr uint32_t INVALID_SAMPLE_SIZE = 0;
28     constexpr int8_t INT8_TRUE = 1;
29 }
30 
31 namespace OHOS {
32 namespace Media {
33 using OHOS::HiviewDFX::HiLog;
34 using ImageSourceNapiFunc = int32_t (*)(struct ImageSourceArgs* args);
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
GetNativeImageSource(struct ImageSourceArgs * args)39 static ImageSource* GetNativeImageSource(struct ImageSourceArgs* args)
40 {
41     if (args == nullptr || args->napi == nullptr || args->napi->nativeImgSrc == nullptr) {
42         return nullptr;
43     }
44     return args->napi->nativeImgSrc.get();
45 }
46 
ParseImageSourceOps(SourceOptions & opts,struct OhosImageSourceOps * ops)47 static void ParseImageSourceOps(SourceOptions &opts, struct OhosImageSourceOps* ops)
48 {
49     opts.baseDensity = ops->density;
50     opts.pixelFormat = static_cast<PixelFormat>(ops->pixelFormat);
51     opts.size.width = ops->size.width;
52     opts.size.height = ops->size.height;
53 }
54 
ParseDecodingOps(DecodeOptions & decOps,struct OhosImageDecodingOps * ops)55 static void ParseDecodingOps(DecodeOptions &decOps, struct OhosImageDecodingOps* ops)
56 {
57     if (ops->sampleSize != INVALID_SAMPLE_SIZE) {
58         decOps.sampleSize = ops->sampleSize;
59     }
60     decOps.rotateNewDegrees = ops->rotate;
61     decOps.editable = (ops->editable == INT8_TRUE);
62     decOps.desiredSize.width = ops->size.width;
63     decOps.desiredSize.height = ops->size.height;
64     decOps.desiredRegion.left = ops->region.x;
65     decOps.desiredRegion.top = ops->region.y;
66     decOps.desiredRegion.width = ops->region.width;
67     decOps.desiredRegion.height = ops->region.height;
68     if (ops->pixelFormat <= static_cast<int32_t>(PixelFormat::CMYK)) {
69         decOps.desiredPixelFormat = PixelFormat(ops->pixelFormat);
70     }
71     decOps.fitDensity = ops->fitDensity;
72 }
73 
ParseImageSourceInfo(struct OhosImageSourceInfo * source,ImageInfo & info)74 static void ParseImageSourceInfo(struct OhosImageSourceInfo* source, ImageInfo &info)
75 {
76     source->alphaType = static_cast<int32_t>(info.alphaType);
77     source->colorSpace = static_cast<int32_t>(info.colorSpace);
78     source->density = info.baseDensity;
79     source->pixelFormat = static_cast<int32_t>(info.pixelFormat);
80     source->size.width = info.size.width;
81     source->size.height = info.size.height;
82 }
83 
UrlToPath(const std::string & path)84 static std::string UrlToPath(const std::string &path)
85 {
86     const std::string filePrefix = "file://";
87     if (path.size() > filePrefix.size() &&
88         (path.compare(0, filePrefix.size(), filePrefix) == 0)) {
89         return path.substr(filePrefix.size());
90     }
91     return path;
92 }
93 
UnwrapNativeObject(napi_env env,napi_value value)94 static ImageSourceNapi* UnwrapNativeObject(napi_env env, napi_value value)
95 {
96     napi_valuetype valueType;
97     napi_typeof(env, value, &valueType);
98     if (valueType != napi_object) {
99         HiLog::Error(LABEL, "UnwrapNativeObject value not a object");
100         return nullptr;
101     }
102     std::unique_ptr<ImageSourceNapi> napi = nullptr;
103     napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&napi));
104     if ((status == napi_ok) && napi != nullptr) {
105         return napi.release();
106     }
107     HiLog::Error(LABEL, "UnwrapNativeObject unwrap error");
108     return nullptr;
109 }
110 
ImageSourceNativeCreate(struct OhosImageSource * source,struct OhosImageSourceOps * ops,std::shared_ptr<ImageSource> & result,ImageResource & resource)111 static int32_t ImageSourceNativeCreate(struct OhosImageSource* source,
112     struct OhosImageSourceOps* ops, std::shared_ptr<ImageSource> &result, ImageResource &resource)
113 {
114     if (source == nullptr) {
115         HiLog::Error(LABEL, "ImageSourceNativeCreate source nullptr");
116         return IMAGE_RESULT_BAD_PARAMETER;
117     }
118     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
119     SourceOptions opts;
120     if (ops != nullptr) {
121         ParseImageSourceOps(opts, ops);
122     }
123     std::unique_ptr<ImageSource> nativeImageSource = nullptr;
124     if (source->uri != nullptr && source->uriSize != SIZE_ZERO) {
125         HiLog::Debug(LABEL, "ImageSourceNativeCreate by path");
126         std::string url(source->uri, source->uriSize);
127         HiLog::Debug(LABEL, "ImageSourceNativeCreate by path %{public}s", url.c_str());
128         auto path = UrlToPath(url);
129         nativeImageSource = ImageSource::CreateImageSource(path, opts, errorCode);
130         resource.type = ImageResourceType::IMAGE_RESOURCE_PATH;
131         resource.path = path;
132     } else if (source->fd != INVALID_FD) {
133         HiLog::Debug(LABEL, "ImageSourceNativeCreate by fd");
134         nativeImageSource = ImageSource::CreateImageSource(source->fd, opts, errorCode);
135         resource.type = ImageResourceType::IMAGE_RESOURCE_FD;
136         resource.fd = source->fd;
137     } else if (source->buffer != nullptr && source->bufferSize != SIZE_ZERO) {
138         HiLog::Debug(LABEL, "ImageSourceNativeCreate by buffer");
139         nativeImageSource = ImageSource::CreateImageSource(source->buffer,
140             source->bufferSize, opts, errorCode);
141         resource.type = ImageResourceType::IMAGE_RESOURCE_BUFFER;
142         resource.buffer = source->buffer;
143         resource.bufferSize = source->bufferSize;
144     }
145     if (nativeImageSource != nullptr) {
146         result = std::move(nativeImageSource);
147         HiLog::Debug(LABEL, "ImageSourceNativeCreate success");
148         return IMAGE_RESULT_SUCCESS;
149     }
150     HiLog::Error(LABEL, "ImageSourceNativeCreate no match source");
151     return IMAGE_RESULT_BAD_PARAMETER;
152 }
153 
ImageSourceCreateNapi(napi_env env,napi_value * res,std::shared_ptr<ImageSource> imageSource,std::shared_ptr<IncrementalPixelMap> incrementalPixelMap,ImageResource * resource)154 static int32_t ImageSourceCreateNapi(napi_env env, napi_value* res,
155     std::shared_ptr<ImageSource> imageSource,
156     std::shared_ptr<IncrementalPixelMap> incrementalPixelMap, ImageResource* resource)
157 {
158     if (ImageSourceNapi::CreateImageSourceNapi(env, res) != SUCCESS) {
159         HiLog::Error(LABEL, "ImageSourceCreateNapi napi create failed");
160         return IMAGE_RESULT_BAD_PARAMETER;
161     }
162     auto napi = UnwrapNativeObject(env, *(res));
163     if (napi == nullptr) {
164         HiLog::Error(LABEL, "ImageSourceCreateNapi napi unwrap check failed");
165         return IMAGE_RESULT_BAD_PARAMETER;
166     }
167 
168     if (imageSource != nullptr) {
169         napi->SetNativeImageSource(imageSource);
170     }
171     if (incrementalPixelMap != nullptr) {
172         napi->SetIncrementalPixelMap(incrementalPixelMap);
173     }
174     if (resource != nullptr) {
175         napi->SetImageResource(*resource);
176     }
177     HiLog::Debug(LABEL, "ImageSourceCreateNapi success");
178     return IMAGE_RESULT_SUCCESS;
179 }
180 
ImageSourceNapiCreate(struct ImageSourceArgs * args)181 static int32_t ImageSourceNapiCreate(struct ImageSourceArgs* args)
182 {
183     if (args == nullptr || args->inEnv == nullptr) {
184         return IMAGE_RESULT_BAD_PARAMETER;
185     }
186     std::shared_ptr<ImageSource> imageSource = nullptr;
187     ImageResource resource;
188     ImageSourceNativeCreate(args->source, args->sourceOps, imageSource, resource);
189     if (imageSource == nullptr) {
190         HiLog::Error(LABEL, "ImageSourceNapiCreate native create failed");
191         return IMAGE_RESULT_BAD_PARAMETER;
192     }
193     if (ImageSourceCreateNapi(args->inEnv, args->outVal, imageSource, nullptr, &resource) != SUCCESS) {
194         HiLog::Error(LABEL, "ImageSourceNapiCreate napi create failed");
195         args->outVal = nullptr;
196         return IMAGE_RESULT_BAD_PARAMETER;
197     }
198     HiLog::Debug(LABEL, "ImageSourceNapiCreate success");
199     return IMAGE_RESULT_SUCCESS;
200 }
201 
ImageSourceNapiCreateIncremental(struct ImageSourceArgs * args)202 static int32_t ImageSourceNapiCreateIncremental(struct ImageSourceArgs* args)
203 {
204     if (args == nullptr || args->inEnv == nullptr) {
205         HiLog::Error(LABEL, "ImageSourceNapiCreateIncremental args or env is nullptr");
206         return IMAGE_RESULT_BAD_PARAMETER;
207     }
208     IncrementalSourceOptions incOpts;
209     if (args->sourceOps != nullptr) {
210         HiLog::Debug(LABEL, "ImageSourceNapiCreate ParseImageSourceOps");
211         ParseImageSourceOps(incOpts.sourceOptions, args->sourceOps);
212     }
213     incOpts.incrementalMode = IncrementalMode::INCREMENTAL_DATA;
214     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
215     std::unique_ptr<ImageSource> imageSource = ImageSource::CreateIncrementalImageSource(incOpts, errorCode);
216     if (imageSource == nullptr) {
217         HiLog::Error(LABEL, "ImageSourceNapiCreateIncremental native imagesource failed");
218         return IMAGE_RESULT_BAD_PARAMETER;
219     }
220     DecodeOptions decodeOpts;
221     uint32_t index = DEFAULT_INDEX;
222     if (args->decodingOps != nullptr) {
223         ParseDecodingOps(decodeOpts, args->decodingOps);
224         index = args->decodingOps->index;
225     }
226     std::unique_ptr<IncrementalPixelMap> incPixelMap = imageSource->CreateIncrementalPixelMap(
227         index, decodeOpts, errorCode);
228     if (incPixelMap == nullptr) {
229         HiLog::Error(LABEL, "ImageSourceNapiCreateIncremental native incremental pixelmap failed");
230         return IMAGE_RESULT_BAD_PARAMETER;
231     }
232     if (ImageSourceCreateNapi(args->inEnv, args->outVal,
233         std::move(imageSource), std::move(incPixelMap), nullptr) != SUCCESS) {
234         HiLog::Error(LABEL, "ImageSourceNapiCreateIncremental napi create failed");
235         args->outVal = nullptr;
236         return IMAGE_RESULT_BAD_PARAMETER;
237     }
238     HiLog::Debug(LABEL, "ImageSourceNapiCreateIncremental success");
239     return IMAGE_RESULT_SUCCESS;
240 }
241 
ImageSourceNapiGetSupportedFormats(struct ImageSourceArgs * args)242 static int32_t ImageSourceNapiGetSupportedFormats(struct ImageSourceArgs* args)
243 {
244     if (args == nullptr) {
245         HiLog::Error(LABEL, "ImageSourceNapiGetSupportedFormats args is nullptr");
246         return IMAGE_RESULT_BAD_PARAMETER;
247     }
248     auto formats = args->outFormats;
249     if (formats == nullptr) {
250         HiLog::Error(LABEL, "ImageSourceNapiGetSupportedFormats args or napi is nullptr");
251         return IMAGE_RESULT_BAD_PARAMETER;
252     }
253     std::set<std::string> formatSet;
254     uint32_t errorCode = ImageSource::GetSupportedFormats(formatSet);
255     if (errorCode != SUCCESS) {
256         HiLog::Error(LABEL, "ImageSourceNapiGetSupportedFormats native failed");
257         return IMAGE_RESULT_BAD_PARAMETER;
258     }
259 
260     size_t formatCount = formatSet.size();
261     if (formats->supportedFormatList == nullptr) {
262         formats->size = formatCount;
263         HiLog::Debug(LABEL, "ImageSourceNapiGetSupportedFormats get count only Success");
264         return IMAGE_RESULT_SUCCESS;
265     } else {
266         formatCount = formats->size;
267     }
268 
269     auto formatList = formats->supportedFormatList;
270     size_t i = 0;
271     for (const std::string& formatStr: formatSet) {
272         if (i >= formatCount) {
273             break;
274         }
275         if (formatList[i] == nullptr || formatList[i]->format == nullptr) {
276             HiLog::Debug(LABEL, "ImageSourceNapiGetSupportedFormats nullptr format out buffer");
277             return IMAGE_RESULT_BAD_PARAMETER;
278         }
279         memcpy_s(formatList[i]->format, formatList[i]->size, formatStr.c_str(), formatStr.size());
280         if (formatList[i]->size > formatStr.size()) {
281             formatList[i]->size = formatStr.size();
282         }
283         i++;
284     }
285     HiLog::Debug(LABEL, "ImageSourceNapiGetSupportedFormats Success");
286     return IMAGE_RESULT_SUCCESS;
287 }
288 
ImageSourceNapiUnwrap(struct ImageSourceArgs * args)289 static int32_t ImageSourceNapiUnwrap(struct ImageSourceArgs* args)
290 {
291     if (args == nullptr || args->inEnv == nullptr || args->inVal == nullptr) {
292         HiLog::Error(LABEL, "ImageSourceNapiUnwrap args or env is nullptr");
293         return IMAGE_RESULT_BAD_PARAMETER;
294     }
295     args->napi = UnwrapNativeObject(args->inEnv, args->inVal);
296     if (args->napi == nullptr) {
297         HiLog::Error(LABEL, "ImageSourceNapiUnwrap UnwrapNativeObject failed");
298         return IMAGE_RESULT_BAD_PARAMETER;
299     }
300     return IMAGE_RESULT_SUCCESS;
301 }
302 
ImageSourceNapiCreatePixelmap(struct ImageSourceArgs * args)303 static int32_t ImageSourceNapiCreatePixelmap(struct ImageSourceArgs* args)
304 {
305     auto native = GetNativeImageSource(args);
306     if (native == nullptr || args->inEnv == nullptr) {
307         HiLog::Error(LABEL, "ImageSourceNapiCreatePixelmap args or napi is nullptr");
308         return IMAGE_RESULT_BAD_PARAMETER;
309     }
310     std::shared_ptr<PixelMap> nativePixelMap = args->napi->GetIncrementalPixelMap();
311     if (nativePixelMap == nullptr) {
312         DecodeOptions decOps;
313         uint32_t index = DEFAULT_INDEX;
314         uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
315         if (args->decodingOps != nullptr) {
316             ParseDecodingOps(decOps, args->decodingOps);
317             index = args->decodingOps->index;
318         }
319         HiLog::Debug(LABEL, "ImageSourceNapiCreatePixelmap CreatePixelMapEx");
320         auto tmpPixelmap = native->CreatePixelMapEx(index, decOps, errorCode);
321         if (tmpPixelmap != nullptr) {
322             nativePixelMap = std::move(tmpPixelmap);
323         }
324     }
325     if (nativePixelMap == nullptr) {
326         HiLog::Error(LABEL, "ImageSourceNapiCreatePixelmap native failed");
327         return IMAGE_RESULT_BAD_PARAMETER;
328     }
329     *(args->outVal) = PixelMapNapi::CreatePixelMap(args->inEnv, nativePixelMap);
330     if (*(args->outVal) == nullptr) {
331         HiLog::Error(LABEL, "ImageSourceNapiCreatePixelmap create pixelmap failed");
332         return IMAGE_RESULT_BAD_PARAMETER;
333     }
334     HiLog::Debug(LABEL, "ImageSourceNapiCreatePixelmap Success");
335     return IMAGE_RESULT_SUCCESS;
336 }
337 
ImageSourceNapiCreatePixelmapList(struct ImageSourceArgs * args)338 static int32_t ImageSourceNapiCreatePixelmapList(struct ImageSourceArgs* args)
339 {
340     auto native = GetNativeImageSource(args);
341     if (native == nullptr || args->inEnv == nullptr) {
342         HiLog::Error(LABEL, "ImageSourceNapiCreatePixelmapList args or napi is nullptr");
343         return IMAGE_RESULT_BAD_PARAMETER;
344     }
345     DecodeOptions decOps;
346     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
347     if (args->decodingOps != nullptr) {
348         ParseDecodingOps(decOps, args->decodingOps);
349     }
350     auto pixelMapList = native->CreatePixelMapList(decOps, errorCode);
351     if (pixelMapList == nullptr) {
352         HiLog::Error(LABEL, "ImageSourceNapiCreatePixelmapList CreatePixelMapList failed");
353         return IMAGE_RESULT_BAD_PARAMETER;
354     }
355     napi_create_array(args->inEnv, args->outVal);
356     size_t i = DEFAULT_INDEX;
357     for (auto &item : *pixelMapList) {
358         auto napiPixelMap = PixelMapNapi::CreatePixelMap(args->inEnv, std::move(item));
359         napi_set_element(args->inEnv, *(args->outVal), i, napiPixelMap);
360         i++;
361     }
362     HiLog::Debug(LABEL, "ImageSourceNapiCreatePixelmapList Success");
363     return IMAGE_RESULT_SUCCESS;
364 }
365 
ImageSourceNapiGetDelayTime(struct ImageSourceArgs * args)366 static int32_t ImageSourceNapiGetDelayTime(struct ImageSourceArgs* args) __attribute__((no_sanitize("cfi")))
367 {
368     auto native = GetNativeImageSource(args);
369     if (native == nullptr || args->outDelayTimes == nullptr) {
370         HiLog::Error(LABEL, "ImageSourceNapiGetDelayTime native image or out is nullptr");
371         return IMAGE_RESULT_BAD_PARAMETER;
372     }
373     auto outDelayTimes = args->outDelayTimes;
374     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
375     auto delayTimes = native->GetDelayTime(errorCode);
376     if (delayTimes == nullptr) {
377         HiLog::Error(LABEL, "ImageSourceNapiGetDelayTime native failed");
378         return IMAGE_RESULT_BAD_PARAMETER;
379     }
380     size_t actCount = (*delayTimes).size();
381     if (outDelayTimes->delayTimeList == nullptr) {
382         HiLog::Error(LABEL, "ImageSourceNapiGetDelayTime get times count only");
383         outDelayTimes->size = actCount;
384         return IMAGE_RESULT_SUCCESS;
385     }
386     if (actCount > outDelayTimes->size) {
387         actCount = outDelayTimes->size;
388     }
389     for (size_t i = SIZE_ZERO; i < actCount; i++) {
390         outDelayTimes->delayTimeList[i] = (*delayTimes)[i];
391     }
392     HiLog::Debug(LABEL, "ImageSourceNapiGetDelayTime Success");
393     return IMAGE_RESULT_SUCCESS;
394 }
395 
ImageSourceNapiGetFrameCount(struct ImageSourceArgs * args)396 static int32_t ImageSourceNapiGetFrameCount(struct ImageSourceArgs* args)
397 {
398     auto native = GetNativeImageSource(args);
399     if (native == nullptr || args->outUint32 == nullptr) {
400         HiLog::Error(LABEL, "ImageSourceNapiGetFrameCount native image or out is nullptr");
401         return IMAGE_RESULT_BAD_PARAMETER;
402     }
403     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
404     *(args->outUint32) = native->GetFrameCount(errorCode);
405     if (errorCode != SUCCESS) {
406         HiLog::Error(LABEL, "ImageSourceNapiGetFrameCount native failed");
407         return IMAGE_RESULT_BAD_PARAMETER;
408     }
409     HiLog::Debug(LABEL, "ImageSourceNapiGetFrameCount Success");
410     return IMAGE_RESULT_SUCCESS;
411 }
412 
ImageSourceNapiGetImageInfo(struct ImageSourceArgs * args)413 static int32_t ImageSourceNapiGetImageInfo(struct ImageSourceArgs* args)
414 {
415     auto native = GetNativeImageSource(args);
416     if (native == nullptr) {
417         HiLog::Error(LABEL, "ImageSourceNapiGetImageInfo native image is nullptr");
418         return IMAGE_RESULT_BAD_PARAMETER;
419     }
420     auto imageSourceInfo = args->outInfo;
421     if (imageSourceInfo == nullptr) {
422         HiLog::Error(LABEL, "ImageSourceNapiGetImageInfo image info is nullptr");
423         return IMAGE_RESULT_BAD_PARAMETER;
424     }
425     ImageInfo imageInfo;
426     uint32_t errorCode = native->GetImageInfo(args->inInt32, imageInfo);
427     if (errorCode != SUCCESS) {
428         HiLog::Error(LABEL, "ImageSourceNapiGetImageInfo native failed");
429         return IMAGE_RESULT_BAD_PARAMETER;
430     }
431     ParseImageSourceInfo(imageSourceInfo, imageInfo);
432     HiLog::Debug(LABEL, "ImageSourceNapiGetImageInfo Success");
433     return IMAGE_RESULT_SUCCESS;
434 }
435 
ImageSourceNapiGetImageProperty(struct ImageSourceArgs * args)436 static int32_t ImageSourceNapiGetImageProperty(
437     struct ImageSourceArgs* args) __attribute__((no_sanitize("cfi")))
438 {
439     auto native = GetNativeImageSource(args);
440     if (native == nullptr) {
441         HiLog::Error(LABEL, "ImageSourceNapiGetImageProperty native image is nullptr");
442         return IMAGE_RESULT_BAD_PARAMETER;
443     }
444     auto propertyKey = args->inPropertyKey;
445     auto propertyVal = args->propertyVal;
446     if (propertyKey == nullptr || propertyKey->value == nullptr || propertyKey->size == SIZE_ZERO) {
447         HiLog::Error(LABEL, "ImageSourceNapiGetImageProperty key is empty");
448         return IMAGE_RESULT_BAD_PARAMETER;
449     }
450     if (propertyVal == nullptr) {
451         HiLog::Error(LABEL, "ImageSourceNapiGetImageProperty out val is nullptr");
452         return IMAGE_RESULT_BAD_PARAMETER;
453     }
454     std::string key(propertyKey->value, propertyKey->size);
455     std::string val;
456     uint32_t errorCode = native->GetImagePropertyString(DEFAULT_INDEX, key, val);
457     if (errorCode != SUCCESS || val.empty()) {
458         HiLog::Error(LABEL, "ImageSourceNapiGetImageProperty native failed");
459         return IMAGE_RESULT_BAD_PARAMETER;
460     }
461     if (propertyVal->value == nullptr) {
462         HiLog::Debug(LABEL, "ImageSourceNapiGetImageProperty return size only");
463         propertyVal->size = val.size();
464         return IMAGE_RESULT_SUCCESS;
465     }
466     memcpy_s(propertyVal->value, propertyVal->size, val.c_str(), val.size());
467     if (propertyVal->size > val.size()) {
468         propertyVal->size = val.size();
469     }
470     HiLog::Debug(LABEL, "ImageSourceNapiGetImageProperty Success");
471     return IMAGE_RESULT_SUCCESS;
472 }
473 
NativePropertyModify(ImageSource * native,ImageResource & imageResource,std::string & key,std::string & val)474 static uint32_t NativePropertyModify(ImageSource* native, ImageResource &imageResource,
475     std::string &key, std::string &val)
476 {
477     auto type = imageResource.type;
478     uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
479     if (type == ImageResourceType::IMAGE_RESOURCE_INVAILD) {
480         HiLog::Error(LABEL, "NativePropertyModify resource is invaild");
481         return IMAGE_RESULT_BAD_PARAMETER;
482     } else if (type == ImageResourceType::IMAGE_RESOURCE_FD && imageResource.fd != INVALID_FD) {
483         HiLog::Debug(LABEL, "NativePropertyModify fd resource");
484         errorCode = native->ModifyImageProperty(DEFAULT_INDEX, key, val, imageResource.fd);
485     } else if (type == ImageResourceType::IMAGE_RESOURCE_PATH && !imageResource.path.empty()) {
486         HiLog::Debug(LABEL, "NativePropertyModify path resource");
487         errorCode = native->ModifyImageProperty(DEFAULT_INDEX, key, val, imageResource.path);
488     } else if (type == ImageResourceType::IMAGE_RESOURCE_BUFFER &&
489         imageResource.buffer != nullptr && imageResource.bufferSize > SIZE_ZERO) {
490         HiLog::Debug(LABEL, "NativePropertyModify buffer resource");
491         errorCode = native->ModifyImageProperty(DEFAULT_INDEX, key, val,
492             imageResource.buffer, imageResource.bufferSize);
493     } else {
494         HiLog::Error(LABEL, "NativePropertyModify %{public}d resource error", type);
495         return IMAGE_RESULT_BAD_PARAMETER;
496     }
497     if (errorCode == SUCCESS) {
498         HiLog::Debug(LABEL, "NativePropertyModify Success");
499         return IMAGE_RESULT_SUCCESS;
500     }
501     HiLog::Error(LABEL, "NativePropertyModify native failed");
502     return IMAGE_RESULT_BAD_PARAMETER;
503 }
504 
ImageSourceNapiModifyImageProperty(struct ImageSourceArgs * args)505 static int32_t ImageSourceNapiModifyImageProperty(struct ImageSourceArgs* args)
506 {
507     auto native = GetNativeImageSource(args);
508     if (native == nullptr) {
509         HiLog::Error(LABEL, "ImageSourceNapiModifyImageProperty native image is nullptr");
510         return IMAGE_RESULT_BAD_PARAMETER;
511     }
512     auto propertyKey = args->inPropertyKey;
513     auto propertyVal = args->propertyVal;
514     if (propertyKey == nullptr || propertyKey->value == nullptr || propertyKey->size == SIZE_ZERO) {
515         HiLog::Error(LABEL, "ImageSourceNapiModifyImageProperty key is empty");
516         return IMAGE_RESULT_BAD_PARAMETER;
517     }
518     if (propertyVal == nullptr || propertyVal->value == nullptr || propertyVal->size == SIZE_ZERO) {
519         HiLog::Error(LABEL, "ImageSourceNapiModifyImageProperty val is nullptr");
520         return IMAGE_RESULT_BAD_PARAMETER;
521     }
522     std::string key(propertyKey->value, propertyKey->size);
523     std::string val(propertyVal->value, propertyVal->size);
524     auto imageResource = args->napi->GetImageResource();
525     auto res = NativePropertyModify(native, imageResource, key, val);
526     return res;
527 }
528 
ProcessIncrementalPixelMap(struct ImageSourceArgs * args,bool completed)529 static int32_t ProcessIncrementalPixelMap(struct ImageSourceArgs* args, bool completed)
530 {
531     auto incPixelMap = args->napi->GetIncrementalPixelMap();
532     if (incPixelMap == nullptr) {
533         HiLog::Error(LABEL, "ProcessIncrementalPixelMap incremental pixelmap is nullptr");
534         return IMAGE_RESULT_BAD_PARAMETER;
535     }
536     uint8_t tmpProgress = 0;
537     uint32_t errCode = incPixelMap->PromoteDecoding(tmpProgress);
538     if (completed) {
539         incPixelMap->DetachFromDecoding();
540     }
541     if (errCode != SUCCESS || (errCode == ERR_IMAGE_SOURCE_DATA_INCOMPLETE && !completed)) {
542         HiLog::Error(LABEL, "ProcessIncrementalPixelMap promote decoding failed");
543         return IMAGE_RESULT_BAD_PARAMETER;
544     }
545     return IMAGE_RESULT_SUCCESS;
546 }
547 
MathMin(uint32_t a,uint32_t b)548 static uint32_t MathMin(uint32_t a, uint32_t b)
549 {
550     if (a < b) {
551         return a;
552     }
553     return b;
554 }
555 
ImageSourceNapiUpdateData(struct ImageSourceArgs * args)556 static int32_t ImageSourceNapiUpdateData(struct ImageSourceArgs* args)
557 {
558     auto native = GetNativeImageSource(args);
559     if (native == nullptr) {
560         HiLog::Error(LABEL, "ImageSourceNapiUpdateData native image is nullptr");
561         return IMAGE_RESULT_BAD_PARAMETER;
562     }
563     auto data = args->inUpdateData;
564     if (data == nullptr || data->buffer == nullptr || data->bufferSize == SIZE_ZERO ||
565         data->offset >= data->bufferSize) {
566         HiLog::Error(LABEL, "ImageSourceNapiUpdateData update data is empty");
567         return IMAGE_RESULT_BAD_PARAMETER;
568     }
569     uint32_t actSize = MathMin((data->bufferSize - data->offset), data->updateLength);
570     bool completed = data->isCompleted == INT8_TRUE;
571     uint32_t errCode = native->UpdateData((data->buffer + data->offset), actSize, completed);
572     if (errCode != SUCCESS) {
573         HiLog::Error(LABEL, "ImageSourceNapiUpdateData update native failed");
574         return IMAGE_RESULT_BAD_PARAMETER;
575     }
576     return ProcessIncrementalPixelMap(args, completed);
577 }
578 
579 static const std::map<int32_t, ImageSourceNapiFunc> g_Functions = {
580     {ENV_FUNC_IMAGE_SOURCE_CREATE, ImageSourceNapiCreate},
581     {ENV_FUNC_IMAGE_SOURCE_CREATE_INCREMENTAL, ImageSourceNapiCreateIncremental},
582     {ENV_FUNC_IMAGE_SOURCE_UNWRAP, ImageSourceNapiUnwrap},
583     {STA_FUNC_IMAGE_SOURCE_GET_SUPPORTED_FORMATS, ImageSourceNapiGetSupportedFormats},
584     {CTX_FUNC_IMAGE_SOURCE_CREATE_PIXELMAP, ImageSourceNapiCreatePixelmap},
585     {CTX_FUNC_IMAGE_SOURCE_CREATE_PIXELMAP_LIST, ImageSourceNapiCreatePixelmapList},
586     {CTX_FUNC_IMAGE_SOURCE_GET_DELAY_TIME, ImageSourceNapiGetDelayTime},
587     {CTX_FUNC_IMAGE_SOURCE_GET_FRAME_COUNT, ImageSourceNapiGetFrameCount},
588     {CTX_FUNC_IMAGE_SOURCE_GET_IMAGE_INFO, ImageSourceNapiGetImageInfo},
589     {CTX_FUNC_IMAGE_SOURCE_GET_IMAGE_PROPERTY, ImageSourceNapiGetImageProperty},
590     {CTX_FUNC_IMAGE_SOURCE_MODIFY_IMAGE_PROPERTY, ImageSourceNapiModifyImageProperty},
591     {CTX_FUNC_IMAGE_SOURCE_UPDATE_DATA, ImageSourceNapiUpdateData}
592 };
593 
594 MIDK_EXPORT
ImageSourceNativeCall(int32_t mode,struct ImageSourceArgs * args)595 int32_t ImageSourceNativeCall(int32_t mode, struct ImageSourceArgs* args)
596 {
597     auto funcSearch = g_Functions.find(mode);
598     if (funcSearch == g_Functions.end()) {
599         return IMAGE_RESULT_BAD_PARAMETER;
600     }
601     return funcSearch->second(args);
602 }
603 #ifdef __cplusplus
604 };
605 #endif
606 }  // namespace Media
607 }  // namespace OHOS