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