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