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 #include "node_api.h"
16 #include "hilog/log.h"
17 #include "multimedia/image_framework/image/image_packer_native.h"
18 #include "multimedia/image_framework/image/pixelmap_native.h"
19 #include "image_packing_test.h"
20 #include <cstdlib>
21 #include <cstdio>
22 #include "image_packer_module_test.h"
23 #include "multimedia/image_framework/image_pixel_map_napi.h"
24 #include <cstring>
25 #include <vector>
26
27 #undef LOG_DOMAIN
28 #undef LOG_TAG
29 #define LOG_DOMAIN 0x3200
30 #define LOG_TAG "IMAGE_TAGLOG"
31
32 #define LOGI(...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
33 #define LOGD(...) ((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
34 #define LOGW(...) ((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
35 #define LOGE(...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
36
37 using namespace std;
38 namespace {
39 static constexpr uint32_t NUM_0 = 0;
40 static constexpr uint32_t NUM_1 = 1;
41 static constexpr uint32_t NUM_2 = 2;
42 static constexpr uint32_t NUM_3 = 3;
43 static constexpr uint32_t NUM_4 = 4;
44 static constexpr uint32_t NUM_5 = 5;
45 static constexpr uint32_t IMAGE_WIDTH = 600;
46 static constexpr uint32_t IMAGE_HEIGHT = 400;
47 uint32_t A = 0xff000000;
48 uint32_t R = 0x00ff0000;
49 uint32_t G = 0x0000ff00;
50 uint32_t B = 0x000000ff;
51 uint32_t colorArray[240000] = { 0 };
52 constexpr size_t SIZE_ZERO = 0;
53 constexpr size_t SIZE_ONE = 1;
54 constexpr size_t SIZE_THREE = 3;
55 constexpr size_t SIZE_FOUR = 4;
56 constexpr size_t SIZE_FIVE = 4;
57 constexpr size_t DEFAULT_PACKING_SIZE = 25 * 1024 * 1024;
58 constexpr uint32_t ARGS_FIRST = 0;
59 constexpr uint32_t ARGS_SECOND = 1;
60 constexpr uint32_t ARGS_THIRD = 2;
61 constexpr uint32_t ARGS_FOURTH = 3;
62 constexpr int32_t INVALID_FD = -1;
63 }
64
65 namespace OHOS {
66 namespace Media {
67 const unsigned int LOG_ID = 0xD002B05;
DEBUG_PTR(void * p)68 inline const char* DEBUG_PTR(void* p) {
69 return (p == nullptr) ? "nullptr" : "not nullptr";
70 }
71
SetUpImage(int type)72 void SetUpImage(int type)
73 {
74 // type 0 -> Red, 1 -> Green, 2 -> Blue
75 uint32_t valueColor = 0;
76 switch (type) {
77 case NUM_0: valueColor = R; break;
78 case NUM_1: valueColor = G; break;
79 case NUM_2: valueColor = B; break;
80 default:
81 break;
82 }
83 for (int i = 0; i < IMAGE_WIDTH * IMAGE_HEIGHT; i++) {
84 colorArray[i] = valueColor;
85 }
86 }
87
CreateArrayBuffer(napi_env env,void * src,size_t srcLen,napi_value * res)88 bool CreateArrayBuffer(napi_env env, void* src, size_t srcLen, napi_value *res)
89 {
90 if (src == nullptr || srcLen == 0) {
91 return false;
92 }
93 void *nativePtr = nullptr;
94 if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) {
95 return false;
96 }
97 if (memcpy(nativePtr, src, srcLen) != src) {
98 return false;
99 }
100 return true;
101 }
102
setImageFormat(napi_env env,napi_value argValue,OH_PackingOptions * options)103 void setImageFormat(napi_env env, napi_value argValue, OH_PackingOptions *options)
104 {
105 size_t mimeTypeSize = 0;
106 Image_MimeType format;
107 if (napi_get_value_string_utf8(env, argValue, nullptr, 0, &mimeTypeSize) != napi_ok) {
108 LOGI("failed to format");
109 return;
110 }
111 char *buffer = static_cast<char *>(malloc((mimeTypeSize + 1) * sizeof(char)));
112 if (buffer == nullptr) {
113 return;
114 }
115 if (napi_get_value_string_utf8(env, argValue, buffer, mimeTypeSize + 1, &mimeTypeSize)) {
116 free(buffer);
117 return;
118 }
119 format.data = buffer;
120 format.size = mimeTypeSize;
121 OH_PackingOptions_SetMimeType(options, &format);
122 LOGI("get format data success %{public}s", format.data);
123 LOGI("get format size success %{public}zu", format.size);
124 free(buffer);
125 return;
126 }
127
128 struct PackingOptionsForSequence {
129 int32_t frameCount;
130 int32_t* delayTimesList;
131 size_t delayTimeListLength = 0;
132 uint32_t* disposalTypesList;
133 size_t disposalTypesLength = 0;
134 uint32_t loopCount = 1;
135 };
136
getLoop(napi_env env,napi_value argValue,PackingOptionsForSequence * ops)137 static void getLoop(napi_env env, napi_value argValue, PackingOptionsForSequence *ops)
138 {
139 if (napi_get_value_uint32(env, argValue, &(ops->loopCount)) != napi_ok) {
140 LOGE("failed to get loop");
141 }
142 LOGI("get loop success %{public}d", ops->loopCount);
143 }
144
getDelayTimes(napi_env env,napi_value argValue,PackingOptionsForSequence * ops)145 static bool getDelayTimes(napi_env env, napi_value argValue, PackingOptionsForSequence *ops)
146 {
147 napi_value delayTimesValue = nullptr;
148 if (napi_get_named_property(env, argValue, "delayTimes", &delayTimesValue) != napi_ok) {
149 LOGE("failed to napi_get_named_property");
150 return false;
151 }
152 bool isDelayTimesArray = false;
153 uint32_t delayTimesSize = 0;
154 if (napi_is_array(env, delayTimesValue, &isDelayTimesArray) != napi_ok) {
155 LOGE("JsPackToFileMultiFrames failed to napi_is_array");
156 return false;
157 }
158 if (!isDelayTimesArray) {
159 LOGE("is not DelayTimesArray");
160 return false;
161 }
162 if (napi_get_array_length(env, delayTimesValue, &delayTimesSize) != napi_ok) {
163 LOGE("Parse delayTime pack napi_get_array_length failed");
164 return false;
165 }
166 LOGI("delayTime size %{public}u", delayTimesSize);
167 ops->delayTimeListLength = delayTimesSize;
168 ops->delayTimesList = static_cast<int32_t *>(malloc((delayTimesSize + 1) * sizeof(int32_t)));
169 if (ops->delayTimesList == nullptr) {
170 LOGE("get delayTimesArray space failed.");
171 return false;
172 }
173 int32_t num = 0;
174 for (size_t i = 0; i < delayTimesSize; i++) {
175 napi_value item1;
176 if (napi_get_element(env, delayTimesValue, i, &item1) != napi_ok) {
177 LOGE("napi_get_element failed %{public}zu", i);
178 return false;
179 }
180 if (napi_get_value_int32(env, item1, &num) != napi_ok) {
181 LOGE("Parse delayTime in item1 failed %{public}zu", i);
182 return false;
183 }
184 ops->delayTimesList[i] = num;
185 LOGI("Parse delayTime in item1 success %{public}d", ops->delayTimesList[i]);
186 }
187 return true;
188 }
189
getDisposalTypes(napi_env env,napi_value argValue,PackingOptionsForSequence * ops)190 static void getDisposalTypes(napi_env env, napi_value argValue, PackingOptionsForSequence *ops)
191 {
192 napi_value disposalTypesValue = nullptr;
193 if (napi_get_named_property(env, argValue, "disposalTypes", &disposalTypesValue) != napi_ok) {
194 LOGE("JsPackToFileMultiFrames failed to napi_get_named_property");
195 return;
196 }
197 bool isDisposalTypesArray = false;
198 uint32_t disposalSize = 0;
199 if (napi_is_array(env, disposalTypesValue, &isDisposalTypesArray) != napi_ok) {
200 LOGE(" failed to napi_is_array");
201 return;
202 }
203 if (!isDisposalTypesArray) {
204 LOGE("is not DisposalTypesArray");
205 return;
206 }
207 if (napi_get_array_length(env, disposalTypesValue, &disposalSize) != napi_ok) {
208 LOGE("Parse disposalTypes pack napi_get_array_length failed");
209 return;
210 }
211 LOGI("disposalSize %{public}u", disposalSize);
212 ops->disposalTypesLength = disposalSize;
213 ops->disposalTypesList = static_cast<uint32_t *>(malloc((disposalSize + 1) * sizeof(uint32_t)));
214 if (ops->disposalTypesList == nullptr) {
215 LOGE("get disposalTypesArray space failed.");
216 return;
217 }
218 uint32_t num = 0;
219 for (size_t i = 0; i < disposalSize; i++) {
220 napi_value item2;
221 if (napi_get_element(env, disposalTypesValue, i, &item2) != napi_ok) {
222 LOGE("napi_get_element failed %{public}zu", i);
223 return;
224 }
225 if (napi_get_value_uint32(env, item2, &num) != napi_ok) {
226 LOGE("Parse disposalTypes in item2 failed %{public}zu", i);
227 return;
228 }
229 ops->disposalTypesList[i] = num;
230 LOGI("Parse disposalTypes in item2 success %{public}u", ops->disposalTypesList[i]);
231 }
232 return;
233 }
234
getFrameCount(napi_env env,napi_value argValue,PackingOptionsForSequence * ops)235 static bool getFrameCount(napi_env env, napi_value argValue, PackingOptionsForSequence *ops)
236 {
237 if (napi_get_value_int32(env, argValue, &(ops->frameCount)) != napi_ok) {
238 LOGE("failed to get frameCount");
239 return false;
240 }
241 LOGI("get frameCount success %{public}d", ops->frameCount);
242 return true;
243 }
244
getFileDescriptor(napi_env env,napi_value argValue)245 int32_t getFileDescriptor(napi_env env, napi_value argValue)
246 {
247 int32_t fd = 0;
248 if (napi_get_value_int32(env, argValue, &fd) != napi_ok) {
249 LOGE("get fd failed ");
250 return fd;
251 }
252 LOGI("get fd success %{public}d", fd);
253 return fd;
254 }
255
createPixelMapList(OH_PixelmapNative ** pixelmaps,int32_t frameCount)256 void createPixelMapList(OH_PixelmapNative **pixelmaps, int32_t frameCount)
257 {
258 OH_Pixelmap_InitializationOptions *options = nullptr;
259 OH_PixelmapInitializationOptions_Create(&options);
260 OH_PixelmapInitializationOptions_SetWidth(options, IMAGE_WIDTH);
261 OH_PixelmapInitializationOptions_SetHeight(options, IMAGE_HEIGHT);
262 OH_PixelmapInitializationOptions_SetPixelFormat(options, NUM_5);
263 OH_PixelmapInitializationOptions_SetAlphaType(options, 1);
264
265 for (int i = 0; i < frameCount; i++) {
266 SetUpImage(i % NUM_3);
267 OH_PixelmapNative_CreatePixelmap((uint8_t *)colorArray,
268 IMAGE_WIDTH * IMAGE_HEIGHT * NUM_4, options, &pixelmaps[i]);
269 }
270 }
271
GetInt32Property(napi_env env,napi_value root,const char * utf8name,int32_t * res)272 static bool GetInt32Property(napi_env env, napi_value root, const char* utf8name, int32_t* res)
273 {
274 napi_value property = nullptr;
275 auto status = napi_get_named_property(env, root, utf8name, &property);
276 if (status != napi_ok || property == nullptr) {
277 LOGE("Get property error %{public}s", utf8name);
278 return false;
279 }
280 return (napi_get_value_int32(env, property, res) == napi_ok);
281 }
282
GetUint32Property(napi_env env,napi_value root,const char * utf8name,uint32_t * res)283 static bool GetUint32Property(napi_env env, napi_value root, const char* utf8name, uint32_t* res)
284 {
285 napi_value property = nullptr;
286 auto status = napi_get_named_property(env, root, utf8name, &property);
287 if (status != napi_ok || property == nullptr) {
288 LOGE("Get property error %{public}s", utf8name);
289 return false;
290 }
291 return (napi_get_value_uint32(env, property, res) == napi_ok);
292 }
293
GetStringProperty(napi_env env,napi_value root,const char * utf8name,char ** buffer,size_t * bufferSize)294 static bool GetStringProperty(napi_env env, napi_value root,
295 const char* utf8name, char** buffer, size_t *bufferSize)
296 {
297 napi_value value = nullptr;
298 auto status = napi_get_named_property(env, root, utf8name, &value);
299 if (status != napi_ok || value == nullptr) {
300 LOGE("Get property error %{public}s", utf8name);
301 return false;
302 }
303
304 if (napi_ok != napi_get_value_string_utf8(env, value, nullptr, SIZE_ZERO, bufferSize)
305 || *bufferSize == SIZE_ZERO) {
306 LOGE("Get napi string length error");
307 return false;
308 }
309
310 *buffer = static_cast<char*>(malloc((*bufferSize) + 1));
311 for (size_t i = SIZE_ZERO; i < (*bufferSize) + 1; i++) {
312 (*buffer)[i] = 0;
313 }
314
315 if (napi_ok != napi_get_value_string_utf8(env, value, *buffer, (*bufferSize) + 1, bufferSize)) {
316 LOGE("Get napi string error");
317 return false;
318 }
319 return (*bufferSize > SIZE_ZERO);
320 }
321
checkArgs(const napi_value * argValue,size_t argCount,size_t want)322 static bool checkArgs(const napi_value* argValue, size_t argCount, size_t want)
323 {
324 if (argCount < want) {
325 LOGE("argCount %{public}zu < want %{public}zu", argCount, want);
326 return false;
327 }
328 for (size_t i = SIZE_ZERO; i < want; i++) {
329 if (argValue[i] == nullptr) {
330 LOGE("argValue[%{public}zu] is nullptr", i);
331 return false;
332 }
333 }
334 return true;
335 }
336
337 struct ImagePackingTestOps {
338 char* format;
339 size_t formatSize;
340 int32_t quality;
341 uint32_t size = SIZE_ZERO;
342 };
343
parseImagePackingOps(napi_env env,napi_value arg,struct ImagePackingTestOps & ops)344 static bool parseImagePackingOps(napi_env env, napi_value arg, struct ImagePackingTestOps &ops)
345 {
346 if (env == nullptr || arg == nullptr) {
347 LOGE("env is %{public}s || arg is %{public}s", DEBUG_PTR(env), DEBUG_PTR(arg));
348 return false;
349 }
350
351 if (!GetStringProperty(env, arg, "format", &(ops.format), &(ops.formatSize))) {
352 return false;
353 }
354 if (!GetInt32Property(env, arg, "quality", &(ops.quality))) {
355 return false;
356 }
357 GetUint32Property(env, arg, "size", &(ops.size));
358 return true;
359 }
createUndefine(napi_env env)360 static napi_value createUndefine(napi_env env)
361 {
362 napi_value udfVal = nullptr;
363 napi_get_undefined(env, &udfVal);
364 return udfVal;
365 }
createResultValue(napi_env env,int32_t resCode,napi_value res=nullptr)366 static napi_value createResultValue(napi_env env, int32_t resCode, napi_value res = nullptr)
367 {
368 napi_value result = nullptr;
369 // JS result like
370 // {code: <error code>, result: <result value>}
371 napi_value nRes = nullptr;
372 napi_create_int32(env, resCode, &nRes);
373 napi_create_object(env, &result);
374 napi_set_named_property(env, result, "code", nRes);
375 if (res != nullptr) {
376 napi_set_named_property(env, result, "result", res);
377 }
378 return result;
379 }
380
parsePackToDataOptionsForSequence(napi_env env,napi_value * argValue,PackingOptionsForSequence * ops)381 static bool parsePackToDataOptionsForSequence(napi_env env, napi_value *argValue, PackingOptionsForSequence *ops)
382 {
383 getLoop(env, argValue[NUM_0], ops);
384 getDisposalTypes(env, argValue[NUM_1], ops);
385 if (!getDelayTimes(env, argValue[NUM_1], ops)) {
386 LOGE("parsePackToDataOptionsForSequence get delayTimes failed");
387 return false;
388 }
389 if (!getFrameCount(env, argValue[NUM_2], ops)) {
390 LOGE("parsePackToDataOptionsForSequence get frameCount failed");
391 return false;
392 }
393 LOGI("parsePackToDataOptionsForSequence success");
394 return true;
395 }
396
setPackingOptionsForSequence(OH_PackingOptionsForSequence * options,PackingOptionsForSequence ops)397 static bool setPackingOptionsForSequence(OH_PackingOptionsForSequence *options, PackingOptionsForSequence ops)
398 {
399 if (OH_PackingOptionsForSequence_SetFrameCount(options, static_cast<uint32_t>(ops.frameCount)) != IMAGE_SUCCESS) {
400 LOGE("OH_PackingOptionsForSequence_SetFrameCount failed");
401 return false;
402 }
403 if (OH_PackingOptionsForSequence_SetDelayTimeList(options, ops.delayTimesList,
404 ops.delayTimeListLength) != IMAGE_SUCCESS) {
405 LOGE("OH_PackingOptionsForSequence_SetDelayTimeList failed");
406 return false;
407 }
408 if (OH_PackingOptionsForSequence_SetDisposalTypes(options, ops.disposalTypesList,
409 ops.disposalTypesLength) != IMAGE_SUCCESS) {
410 LOGE("OH_PackingOptionsForSequence_SetDisposalTypes failed");
411 return false;
412 }
413 if (OH_PackingOptionsForSequence_SetLoopCount(options, ops.loopCount)!= IMAGE_SUCCESS) {
414 LOGE("OH_PackingOptionsForSequence_SetLoopCount failed");
415 return false;
416 }
417 LOGI("setPackingOptionsForSequence success");
418 return true;
419 }
420
checkPackingOptionsForSequence(OH_PackingOptionsForSequence * options,PackingOptionsForSequence ops)421 static bool checkPackingOptionsForSequence(OH_PackingOptionsForSequence *options, PackingOptionsForSequence ops)
422 {
423 PackingOptionsForSequence tmpOpts;
424 uint32_t frameCount = 0;
425 Image_ErrorCode reslut = OH_PackingOptionsForSequence_GetFrameCount(options, &frameCount);
426 LOGI("Set frameCount = %{public}d", ops.frameCount);
427 LOGI("Get frameCount = %{public}u", frameCount);
428 if (reslut != IMAGE_SUCCESS || ops.frameCount != static_cast<int32_t>(frameCount)) {
429 LOGE("frameCount not matching");
430 return false;
431 }
432 tmpOpts.delayTimeListLength = ops.delayTimeListLength;
433 std::vector<int32_t> delayTimeList(tmpOpts.delayTimeListLength);
434 reslut = OH_PackingOptionsForSequence_GetDelayTimeList(options, delayTimeList.data(), ops.delayTimeListLength);
435 if (reslut != IMAGE_SUCCESS) {
436 LOGE("OH_PackingOptionsForSequence_GetDelayTimeList failed");
437 return false;
438 }
439 if (ops.disposalTypesLength != 0) {
440 tmpOpts.disposalTypesLength = ops.disposalTypesLength;
441 std::vector<uint32_t> disposalTypes(tmpOpts.disposalTypesLength);
442 reslut = OH_PackingOptionsForSequence_GetDisposalTypes(
443 options, disposalTypes.data(), tmpOpts.disposalTypesLength);
444 if (reslut != IMAGE_SUCCESS) {
445 LOGE("OH_PackingOptionsForSequence_GetDisposalTypes failed");
446 return false;
447 }
448 }
449 reslut = OH_PackingOptionsForSequence_GetLoopCount(options, &(tmpOpts.loopCount));
450 LOGI("Set loopCount = %{public}u", ops.loopCount);
451 LOGI("Get loopCount = %{public}u", tmpOpts.loopCount);
452 if (tmpOpts.loopCount != ops.loopCount || reslut != IMAGE_SUCCESS) {
453 LOGE("loopCount not matching");
454 return false;
455 }
456 return true;
457 }
458
JsPackToDataMultiFrames(napi_env env,napi_callback_info info)459 napi_value ImagePackingNDKTest::JsPackToDataMultiFrames(napi_env env, napi_callback_info info)
460 {
461 napi_value result = nullptr;
462 napi_value resultBuffer = nullptr;
463 napi_get_undefined(env, &result);
464 napi_get_undefined(env, &resultBuffer);
465 napi_value thisVar = nullptr;
466 napi_value argValue[NUM_3] = {0};
467 size_t argCount = NUM_3;
468 if (napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr) != napi_ok) {
469 LOGE("JsPackToDataMultiFrames failed to parse params");
470 return result;
471 }
472 OH_PackingOptionsForSequence *options = nullptr;
473 OH_PackingOptionsForSequence_Create(&options);
474 PackingOptionsForSequence ops;
475 if (!parsePackToDataOptionsForSequence(env, argValue, &ops)) {
476 LOGE("JsPackToDataMultiFrames failed to parse packing options");
477 return result;
478 }
479 if (!setPackingOptionsForSequence(options, ops)) {
480 LOGE("JsPackToDataMultiFrames failed to set packing options");
481 return result;
482 }
483 if (!checkPackingOptionsForSequence(options, ops)) {
484 LOGE("JsPackToDataMultiFrames failed to check packing options");
485 return result;
486 }
487 OH_PixelmapNative *pixelmaps[ops.frameCount];
488 createPixelMapList(pixelmaps, ops.frameCount);
489
490 size_t outDataSize = 10000;
491 uint8_t outData[outDataSize];
492 ImagePackerModuleTest ipmt;
493 Image_ErrorCode ret = ipmt.PackToDataMultiFrames(options, pixelmaps, ops.frameCount, outData, &outDataSize);
494 if (ret != IMAGE_SUCCESS) {
495 LOGE("JsPackToDataMultiFrames failed");
496 } else {
497 CreateArrayBuffer(env, outData, outDataSize, &resultBuffer);
498 }
499 result = createResultValue(env, ret, resultBuffer);
500 OH_PackingOptionsForSequence_Release(options);
501 return result;
502 }
503
JsPackToDataMultiFramesError(napi_env env,napi_callback_info info)504 napi_value ImagePackingNDKTest::JsPackToDataMultiFramesError(napi_env env, napi_callback_info info)
505 {
506 napi_value result = nullptr;
507 napi_value undefined = nullptr;
508 napi_get_undefined(env, &result);
509 napi_get_undefined(env, &undefined);
510 napi_value thisVar = nullptr;
511 napi_value argValue[NUM_4] = {0};
512 size_t argCount = NUM_4;
513 if (napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr) != napi_ok) {
514 LOGE("JsPackToDataMultiFramesError failed to parse params");
515 return result;
516 }
517 OH_PackingOptionsForSequence *options = nullptr;
518 OH_PackingOptionsForSequence_Create(&options);
519 PackingOptionsForSequence ops;
520 if (!parsePackToDataOptionsForSequence(env, argValue, &ops)) {
521 LOGE("JsPackToDataMultiFrames failed to parse packing options");
522 return result;
523 }
524 if (!setPackingOptionsForSequence(options, ops)) {
525 LOGE("JsPackToDataMultiFrames failed to set packing options");
526 return result;
527 }
528 if (!checkPackingOptionsForSequence(options, ops)) {
529 LOGE("JsPackToDataMultiFrames failed to check packing options");
530 return result;
531 }
532 uint32_t mode;
533 if (napi_get_value_uint32(env, argValue[NUM_3], &mode) != napi_ok) {
534 LOGE("Parse error mode in argValue failed");
535 return result;
536 }
537 OH_PixelmapNative *pixelmaps[ops.frameCount];
538 createPixelMapList(pixelmaps, ops.frameCount);
539
540 size_t outDataSize = 10000;
541 uint8_t outData[outDataSize];
542 ImagePackerModuleTest ipmt;
543 packMultiFramesOptions opts = {options, pixelmaps, ops.frameCount, mode};
544 Image_ErrorCode ret = ipmt.PackToDataMultiFramesError(&opts, outData, &outDataSize);
545 if (ret != IMAGE_SUCCESS) {
546 LOGE("PackToDataFromPixelmapSequence failed");
547 }
548 OH_PackingOptionsForSequence_Release(options);
549 result = createResultValue(env, ret, undefined);
550 return result;
551 }
552
parsePackToFileOptionsForSequence(napi_env env,napi_value * argValue,PackingOptionsForSequence * ops)553 static bool parsePackToFileOptionsForSequence(napi_env env, napi_value *argValue, PackingOptionsForSequence *ops)
554 {
555 getLoop(env, argValue[NUM_3], ops);
556 getDisposalTypes(env, argValue[NUM_0], ops);
557 if (!getDelayTimes(env, argValue[NUM_0], ops)) {
558 LOGE("parsePackToFileOptionsForSequence get delayTimes failed");
559 return false;
560 }
561 if (!getFrameCount(env, argValue[NUM_2], ops)) {
562 LOGE("parsePackToFileOptionsForSequence get frameCount failed");
563 return false;
564 }
565 LOGI("parsePackToDataOptionsForSequence success");
566 return true;
567 }
568
JsPackToFileMultiFrames(napi_env env,napi_callback_info info)569 napi_value ImagePackingNDKTest::JsPackToFileMultiFrames(napi_env env, napi_callback_info info)
570 {
571 napi_value result = nullptr;
572 napi_value undefined = nullptr;
573 napi_get_undefined(env, &result);
574 napi_get_undefined(env, &undefined);
575 napi_value thisVar = nullptr;
576 napi_value argValue[NUM_4] = {0};
577 size_t argCount = NUM_4;
578 if (napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr) != napi_ok) {
579 LOGE("failed to parse params");
580 return result;
581 }
582
583 OH_PackingOptionsForSequence *options = nullptr;
584 OH_PackingOptionsForSequence_Create(&options);
585 PackingOptionsForSequence ops;
586 int32_t fd = getFileDescriptor(env, argValue[NUM_1]);
587 if (!parsePackToFileOptionsForSequence(env, argValue, &ops)) {
588 LOGE("JsPackToFileMultiFrames failed to parse packing options");
589 return result;
590 }
591 if (!setPackingOptionsForSequence(options, ops)) {
592 LOGE("JsPackToFileMultiFrames failed to set packing options");
593 return result;
594 }
595 if (!checkPackingOptionsForSequence(options, ops)) {
596 LOGE("JsPackToFileMultiFrames failed to check packing options");
597 return result;
598 }
599 OH_PixelmapNative *pixelmaps[ops.frameCount];
600 createPixelMapList(pixelmaps, ops.frameCount);
601
602 ImagePackerModuleTest ipmt;
603 Image_ErrorCode ret = ipmt.PackToFileMultiFrames(options, pixelmaps, ops.frameCount, fd);
604 if (ret != IMAGE_SUCCESS) {
605 LOGE("JsPackToFileMultiFrames failed");
606 }
607 LOGI("ret = %{public}d", ret);
608 OH_PackingOptionsForSequence_Release(options);
609 result = createResultValue(env, ret, undefined);
610 return result;
611 }
612
JsPackToFileMultiFramesError(napi_env env,napi_callback_info info)613 napi_value ImagePackingNDKTest::JsPackToFileMultiFramesError(napi_env env, napi_callback_info info)
614 {
615 napi_value result = nullptr;
616 napi_value undefined = nullptr;
617 napi_get_undefined(env, &result);
618 napi_get_undefined(env, &undefined);
619 napi_value thisVar = nullptr;
620 napi_value argValue[NUM_5] = {0};
621 size_t argCount = NUM_5;
622 if (napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr) != napi_ok) {
623 LOGE("failed to parse params");
624 return result;
625 }
626
627 OH_PackingOptionsForSequence *options = nullptr;
628 OH_PackingOptionsForSequence_Create(&options);
629 PackingOptionsForSequence ops;
630 int32_t fd = getFileDescriptor(env, argValue[NUM_1]);
631 if (!parsePackToFileOptionsForSequence(env, argValue, &ops)) {
632 LOGE("JsPackToFileMultiFrames failed to parse packing options");
633 return result;
634 }
635 if (!setPackingOptionsForSequence(options, ops)) {
636 LOGE("JsPackToFileMultiFrames failed to set packing options");
637 return result;
638 }
639 if (!checkPackingOptionsForSequence(options, ops)) {
640 LOGE("JsPackToFileMultiFrames failed to check packing options");
641 return result;
642 }
643 uint32_t mode;
644 if (napi_get_value_uint32(env, argValue[NUM_4], &mode) != napi_ok || mode == BAD_PARAMETER_OUTDATA) {
645 LOGE("Parse error mode in argValue failed");
646 return result;
647 }
648 OH_PixelmapNative *pixelmaps[ops.frameCount];
649 createPixelMapList(pixelmaps, ops.frameCount);
650
651 packMultiFramesOptions opts = {options, pixelmaps, ops.frameCount, mode};
652 ImagePackerModuleTest ipmt;
653 Image_ErrorCode ret = ipmt.PackToFileMultiFramesError(&opts, fd);
654 if (ret != IMAGE_SUCCESS) {
655 LOGE("PackToFileFromPixelmapSequence failed");
656 }
657 LOGI("ret = %{public}d", ret);
658 OH_PackingOptionsForSequence_Release(options);
659 result = createResultValue(env, ret, undefined);
660 return result;
661 }
662
Create(napi_env env,napi_callback_info info)663 napi_value ImagePackingNDKTest::Create(napi_env env, napi_callback_info info)
664 {
665 napi_value imagePacker = nullptr;
666 int32_t res = OH_ImagePacker_Create(env, &imagePacker);
667 return createResultValue(env, res, imagePacker);
668 }
669
getNativeImagePacker(napi_env env,napi_callback_info info,napi_value * argValue,size_t & argCount)670 static ImagePacker_Native* getNativeImagePacker(napi_env env, napi_callback_info info,
671 napi_value* argValue, size_t &argCount)
672 {
673 napi_value thisVar = nullptr;
674 if (argValue == nullptr || argCount == SIZE_ZERO) {
675 LOGE("Invaild input!");
676 return nullptr;
677 }
678 if (napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr) != napi_ok) {
679 return nullptr;
680 }
681 return OH_ImagePacker_InitNative(env, argValue[ARGS_FIRST]);
682 }
683
InitNative(napi_env env,napi_callback_info info)684 napi_value ImagePackingNDKTest::InitNative(napi_env env, napi_callback_info info)
685 {
686 napi_value argValue[SIZE_ONE] = {0};
687 size_t argCount = SIZE_ONE;
688
689 ImagePacker_Native* native = getNativeImagePacker(env, info, argValue, argCount);
690 if (native == nullptr) {
691 return createUndefine(env);
692 }
693 return createResultValue(env, OHOS_IMAGE_RESULT_SUCCESS);
694 }
695
696 // PackToData(packer, source, opts:{format, quality, size})<{code, result}>
PackToData(napi_env env,napi_callback_info info)697 napi_value ImagePackingNDKTest::PackToData(napi_env env, napi_callback_info info)
698 {
699 napi_value argValue[SIZE_THREE] = {0};
700 size_t argCount = SIZE_THREE;
701 ImagePacker_Native* native = getNativeImagePacker(env, info, argValue, argCount);
702 if (native == nullptr || !checkArgs(argValue, argCount, SIZE_THREE)) {
703 LOGE("argValue check failed");
704 return createUndefine(env);
705 }
706 struct ImagePackingTestOps ops;
707 if (!parseImagePackingOps(env, argValue[ARGS_THIRD], ops)) {
708 LOGE("packing ops parse failed");
709 return createResultValue(env, IMAGE_RESULT_INVALID_PARAMETER);
710 }
711
712 ImagePacker_Opts packerOpts;
713 packerOpts.format = ops.format;
714 packerOpts.quality = ops.quality;
715
716 size_t dataSize = (ops.size > SIZE_ZERO) ? ops.size : DEFAULT_PACKING_SIZE;
717 napi_value nValue = nullptr;
718 uint8_t *data = nullptr;
719 if (napi_create_arraybuffer(env, dataSize,
720 reinterpret_cast<void**>(&data), &nValue) != napi_ok || data == nullptr) {
721 LOGE("packing create data failed");
722 return createUndefine(env);
723 }
724 int32_t res = OH_ImagePacker_PackToData(native,
725 argValue[ARGS_SECOND], &packerOpts, data, &dataSize);
726 if (ops.format != nullptr) {
727 free(ops.format);
728 ops.format = nullptr;
729 }
730 LOGI("packing act size %{public}zu", dataSize);
731 return createResultValue(env, res, nValue);
732 }
733
734 // packToFile(packer, source, fd, opts:{format, quality})<{code, result}>
PackToFile(napi_env env,napi_callback_info info)735 napi_value ImagePackingNDKTest::PackToFile(napi_env env, napi_callback_info info)
736 {
737 napi_value argValue[SIZE_FOUR] = {0};
738 size_t argCount = SIZE_FOUR;
739 ImagePacker_Native* native = getNativeImagePacker(env, info, argValue, argCount);
740 if (native == nullptr || !checkArgs(argValue, argCount, SIZE_FOUR)) {
741 LOGE("argValue check failed");
742 return createUndefine(env);
743 }
744 int32_t fd = INVALID_FD;
745 if (napi_ok != napi_get_value_int32(env, argValue[ARGS_THIRD], &fd)) {
746 LOGE("Fd arg failed");
747 return createUndefine(env);
748 }
749
750 struct ImagePackingTestOps ops;
751 if (!parseImagePackingOps(env, argValue[ARGS_FOURTH], ops)) {
752 LOGE("packing ops parse failed");
753 return createResultValue(env, IMAGE_RESULT_INVALID_PARAMETER);
754 }
755
756 ImagePacker_Opts packerOpts;
757 packerOpts.format = ops.format;
758 packerOpts.quality = ops.quality;
759
760 int32_t res = OH_ImagePacker_PackToFile(native, argValue[ARGS_SECOND], &packerOpts, fd);
761 if (ops.format != nullptr) {
762 free(ops.format);
763 ops.format = nullptr;
764 }
765 return createResultValue(env, res, nullptr);
766 }
767
Release(napi_env env,napi_callback_info info)768 napi_value ImagePackingNDKTest::Release(napi_env env, napi_callback_info info)
769 {
770 napi_value argValue[SIZE_ONE] = {0};
771 size_t argCount = SIZE_ONE;
772 ImagePacker_Native* native = getNativeImagePacker(env, info, argValue, argCount);
773 if (native == nullptr) {
774 LOGE("argValue check failed");
775 return createResultValue(env, IMAGE_RESULT_INVALID_PARAMETER);
776 }
777 int32_t res = OH_ImagePacker_Release(native);
778 return createResultValue(env, res);
779 }
780 }
781 }
782 EXTERN_C_START
ModuleRegister(napi_env env,napi_value exports)783 static napi_value ModuleRegister(napi_env env, napi_value exports)
784 {
785 napi_property_descriptor props [] = {
786 {"create", nullptr, OHOS::Media::ImagePackingNDKTest::Create, nullptr, nullptr, nullptr, napi_static, nullptr},
787 {"initNative", nullptr, OHOS::Media::ImagePackingNDKTest::InitNative, nullptr, nullptr, nullptr, napi_static,
788 nullptr},
789 {"packToData", nullptr, OHOS::Media::ImagePackingNDKTest::PackToData, nullptr, nullptr, nullptr, napi_static,
790 nullptr},
791 {"packToFile", nullptr, OHOS::Media::ImagePackingNDKTest::PackToFile, nullptr, nullptr, nullptr, napi_static,
792 nullptr},
793 {"release", nullptr, OHOS::Media::ImagePackingNDKTest::Release, nullptr, nullptr, nullptr, napi_static,
794 nullptr},
795 {"JsPackToDataMultiFrames", nullptr, OHOS::Media::ImagePackingNDKTest::JsPackToDataMultiFrames, nullptr,
796 nullptr, nullptr, napi_static, nullptr},
797 {"JsPackToDataMultiFramesError", nullptr, OHOS::Media::ImagePackingNDKTest::JsPackToDataMultiFramesError,
798 nullptr, nullptr, nullptr, napi_static, nullptr },
799 {"JsPackToFileMultiFrames", nullptr, OHOS::Media::ImagePackingNDKTest::JsPackToFileMultiFrames, nullptr,
800 nullptr, nullptr, napi_static, nullptr},
801 {"JsPackToFileMultiFramesError", nullptr, OHOS::Media::ImagePackingNDKTest::JsPackToFileMultiFramesError,
802 nullptr, nullptr, nullptr, napi_static, nullptr },
803 };
804 napi_define_properties(env, exports, sizeof(props) / sizeof(props[ARGS_FIRST]), props);
805 return exports;
806 }
807 EXTERN_C_END
808 static napi_module demoModule = {
809 .nm_version =1,
810 .nm_flags = 0,
811 .nm_filename = nullptr,
812 .nm_register_func = ModuleRegister,
813 .nm_modname = "entry",
814 .nm_priv = ((void *)0),
815 .reserved = { 0 },
816 };
RegisterEntryModule(void)817 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
818