1 /*
2  * Copyright (C) 2024 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 <dlfcn.h>
17 #include <fcntl.h>
18 #include <iostream>
19 #include <linux/kd.h>
20 
21 #include <multimedia/image_framework/image/pixelmap_native.h>
22 #include <multimedia/image_framework/image/image_packer_native.h>
23 #include <multimedia/image_framework/image/image_source_native.h>
24 #include "multimedia/image_framework/image_pixel_map_mdk.h"
25 #include "napi/native_api.h"
26 
27 #include <string>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 
32 #undef LOG_DOMAIN
33 #undef LOG_TAG
34 #define LOG_DOMAIN 0x3200
35 #define LOG_TAG "MY_TAG"
36 
37 namespace {
38     const uint32_t NUM_0 = 0;
39     const uint32_t NUM_1 = 1;
40     const uint32_t NUM_2 = 2;
41     const uint32_t NUM_3 = 3;
42     const uint32_t NUM_4 = 4;
43     const uint32_t NUM_5 = 5;
44     const uint32_t NUM_6 = 6;
45     const uint32_t MAX_BUFFER_SIZE = 512;
46     const uint32_t MAX_COLOR_SIZE = 96;
47     const uint32_t MAX_QUALITY_SIZE = 98;
48     constexpr int8_t ARGB_8888_BYTES = 4;
49 }
50 
51 const char *LOG_APP = "ImageNDK";
52 const char* VPE_SO_NAME = "/sys_prod/lib64/VideoProcessingEngine/libaihdr_engine.so";
53 
OHLog(const char *module, const char *format, ...)54 static void OHLog(const char *module, const char *format, ...)
55 {
56 
57     char buffer[MAX_BUFFER_SIZE];
58     va_list args;
59     va_start(args, format);
60     vsnprintf(buffer, sizeof(buffer), format, args);
61     va_end(args);
62 
63     printf("[%s] %s\n", module, buffer);
64 }
65 
66 #define OH_LOG_ERROR(module, format, ...)                                                                              \
67     do {                                                                                                               \
68         OHLog(module, format, ##__VA_ARGS__);                                                                          \
69     } while (false)
70 
71 
72 #define OH_LOG_INFO(module, format, ...)                                                                               \
73     do {                                                                                                               \
74         OHLog(module, format, ##__VA_ARGS__);                                                                          \
75     } while (false)
76 
getJsResult(napi_env env, int result)77 static napi_value getJsResult(napi_env env, int result)
78 {
79     napi_value resultNapi = nullptr;
80     napi_create_int32(env, result, &resultNapi);
81     return resultNapi;
82 }
83 
TestInitializationOptionsSetRowStrideNormal(napi_env env, napi_callback_info info)84 static napi_value TestInitializationOptionsSetRowStrideNormal(napi_env env, napi_callback_info info)
85 {
86     napi_value argValue[NUM_1] = {0};
87     size_t argCount = NUM_1;
88     if (napi_get_cb_info(env, info, &argCount, argValue, nullptr, nullptr) != napi_ok || argCount < NUM_1 ||
89         argValue[NUM_0] == nullptr) {
90         OH_LOG_ERROR(LOG_APP, "napi_get_cb_info failed, argCount: %{public}zu.", argCount);
91         return getJsResult(env, IMAGE_BAD_PARAMETER);
92     }
93     int32_t rowStride = 0;
94     napi_get_value_int32(env, argValue[0], &rowStride);
95     OH_Pixelmap_InitializationOptions *opts = nullptr;
96     Image_ErrorCode errCode = OH_PixelmapInitializationOptions_Create(&opts);
97     if (errCode != IMAGE_SUCCESS) {
98         OH_LOG_ERROR(LOG_APP, "OH_PixelmapInitializationOptions_Create failed, errCode: %{public}d.", errCode);
99         return getJsResult(env, errCode);
100     }
101     errCode = OH_PixelmapInitializationOptions_SetRowStride(opts, rowStride);
102     if (errCode != IMAGE_SUCCESS) {
103         return getJsResult(env, errCode);
104     }
105     int32_t getStride = 0;
106     errCode = OH_PixelmapInitializationOptions_GetRowStride(opts, &getStride);
107     if (errCode != IMAGE_SUCCESS) {
108         return getJsResult(env, errCode);
109     }
110     if (getStride != rowStride) {
111         return getJsResult(env, IMAGE_UNKNOWN_ERROR);
112     }
113     errCode = OH_PixelmapInitializationOptions_Release(opts);
114     if (errCode != IMAGE_SUCCESS) {
115         OH_LOG_ERROR(LOG_APP, "OH_PixelmapInitializationOptions_Release failed, errCode: %{public}d.", errCode);
116         return getJsResult(env, errCode);
117     }
118     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestInitializationOptionsSetRowStrideNormal success.");
119     return getJsResult(env, IMAGE_SUCCESS);
120 }
121 
TestCreatePixelMapWithStrideAbnormal(napi_env env, napi_callback_info info)122 static napi_value TestCreatePixelMapWithStrideAbnormal(napi_env env, napi_callback_info info)
123 {
124     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest Test OH_Pixelmap_CreatePixelMapWithStride will call.");
125     void* buffer = nullptr;
126     size_t bufferSize = 0;
127     struct OhosPixelMapCreateOps createOps;
128     napi_value pixelmap = nullptr;
129     size_t rowStride = -1; // set a error row stride
130     std::cout << "cout: ImagePixelmapNativeCTest Test will call OH_Pixelmap_CreatePixelMapWithStride." << std::endl;
131     int32_t res = OH_PixelMap_CreatePixelMapWithStride(env, createOps, buffer, bufferSize, rowStride, &pixelmap);
132     std::cout << "cout: ImagePixelmapNativeCTest Test OH_Pixelmap_CreatePixelMapWithStride." << std::endl;
133     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest Test OH_Pixelmap_CreatePixelMapWithStride, res: %{public}zu.", res);
134     if (res != IMAGE_RESULT_GET_DATA_ABNORMAL) {
135         return getJsResult(env, res);
136     }
137     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestCreatePixelMapWithStrideAbnormal success.");
138     return getJsResult(env, 0);
139 }
140 
TestNativeScaleWithAntiAliasingAbnormal(napi_env env, napi_callback_info info)141 static napi_value TestNativeScaleWithAntiAliasingAbnormal(napi_env env, napi_callback_info info)
142 {
143     float x = 1.5;
144     float y = 1.5;
145     OH_PixelmapNative *pixelmapNative = nullptr;
146     Image_ErrorCode errCode = OH_PixelmapNative_ScaleWithAntiAliasing(pixelmapNative, x, y,
147         OH_PixelmapNative_AntiAliasing_HIGH);
148     if (errCode != IMAGE_BAD_PARAMETER) {
149         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_ScaleWithAntiAliasing failed, errCode: %{public}d.", errCode);
150         return getJsResult(env, errCode);
151     }
152     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeScaleWithAntiAliasingNormal success.");
153     return getJsResult(env, IMAGE_SUCCESS);
154 }
155 
TestScaleWithAntiAliasingAbnormal(napi_env env, napi_callback_info info)156 static napi_value TestScaleWithAntiAliasingAbnormal(napi_env env, napi_callback_info info)
157 {
158     napi_value result = nullptr;
159     napi_value thisVar = nullptr;
160     napi_value argValue[NUM_2] = {0};
161     size_t argCount = NUM_2;
162 
163     napi_get_undefined(env, &result);
164     if (napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr) != napi_ok ||
165         argCount < NUM_2 || argValue[NUM_0] == nullptr || argValue[NUM_1] == nullptr) {
166         return result;
167     }
168     NativePixelMap* native = nullptr;
169     double x = 0;
170     double y = 0;
171     if (napi_get_value_double(env, argValue[NUM_0], &x) != napi_ok ||
172         napi_get_value_double(env, argValue[NUM_1], &y) != napi_ok) {
173         return result;
174     }
175 
176     int32_t errCode = OH_PixelMap_ScaleWithAntiAliasing(
177         native, static_cast<float>(x), static_cast<float>(y), OH_PixelMap_AntiAliasing_HIGH);
178     if (errCode != IMAGE_RESULT_BAD_PARAMETER) {
179         OH_LOG_ERROR(LOG_APP, "OH_Pixelmap_ScaleWithAntiAliasing failed, errCode: %{public}d.", errCode);
180         return getJsResult(env, errCode);
181     }
182     return getJsResult(env, IMAGE_RESULT_SUCCESS);
183 }
184 
TestNativeGetNativeBufferAbnormal(napi_env env, napi_callback_info info)185 static napi_value TestNativeGetNativeBufferAbnormal(napi_env env, napi_callback_info info)
186 {
187     OH_PixelmapNative *pixelmapNative = nullptr;
188     OH_NativeBuffer **nativeBUffer = nullptr;
189     Image_ErrorCode errCode = OH_PixelmapNative_GetNativeBuffer(pixelmapNative, nativeBUffer);
190     if (errCode != IMAGE_BAD_PARAMETER) {
191         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_GetNativeBuffer failed, errCode: %{public}d.", errCode);
192         return getJsResult(env, errCode);
193     }
194     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeGetNativeBufferAbnormal success.");
195     return getJsResult(env, IMAGE_SUCCESS);
196 }
197 
TestNativeSetMetaDataNull(napi_env env, napi_callback_info info)198 static napi_value TestNativeSetMetaDataNull(napi_env env, napi_callback_info info)
199 {
200     OH_PixelmapNative *pixelmapNative = nullptr;
201     OH_Pixelmap_HdrMetadataValue *value = nullptr;
202     Image_ErrorCode errCode = OH_PixelmapNative_SetMetadata(pixelmapNative, HDR_METADATA_TYPE, value);
203     if (errCode != IMAGE_BAD_PARAMETER) {
204         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_SetMetadata failed, errCode: %{public}d.", errCode);
205         return getJsResult(env, errCode);
206     }
207     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeSetMetaDataNull success.");
208     return getJsResult(env, IMAGE_SUCCESS);
209 }
210 
TestNativeGetMetaDataNull(napi_env env, napi_callback_info info)211 static napi_value TestNativeGetMetaDataNull(napi_env env, napi_callback_info info)
212 {
213     OH_PixelmapNative *pixelmapNative = nullptr;
214     OH_Pixelmap_HdrMetadataValue **value = nullptr;
215     Image_ErrorCode errCode = OH_PixelmapNative_GetMetadata(pixelmapNative, HDR_METADATA_TYPE, value);
216     if (errCode != IMAGE_BAD_PARAMETER) {
217         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_GetMetadata failed, errCode: %{public}d.", errCode);
218         return getJsResult(env, errCode);
219     }
220     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeGetMetaDataNull success.");
221     return getJsResult(env, IMAGE_SUCCESS);
222 }
223 
TestNativeSetMemoryName(napi_env env, napi_callback_info info)224 static napi_value TestNativeSetMemoryName(napi_env env, napi_callback_info info)
225 {
226     OH_PixelmapNative *pixelmap = nullptr;
227     char name[] = "testName";
228     size_t len = strlen(name);
229     Image_ErrorCode errCode = OH_PixelmapNative_SetMemoryName(pixelmap, name, &len);
230     if (errCode != IMAGE_BAD_PARAMETER) {
231         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_SetMemoryName failed, errCode: %{public}d.", errCode);
232         return getJsResult(env, errCode);
233     }
234     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeSetMemoryName success.");
235     return getJsResult(env, IMAGE_SUCCESS);
236 }
237 
TestNativeGetArgbPixels(napi_env env, napi_callback_info info)238 static napi_value TestNativeGetArgbPixels(napi_env env, napi_callback_info info)
239 {
240     OH_PixelmapNative *pixelMap = nullptr;
241     size_t dataSize = ARGB_8888_BYTES;
242     uint8_t result[ARGB_8888_BYTES];
243     Image_ErrorCode errCode = OH_PixelmapNative_GetArgbPixels(pixelMap, result, &dataSize);
244     if (errCode != IMAGE_BAD_PARAMETER) {
245         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_GetArgbPixels failed, errCode: %{public}d.", errCode);
246         return getJsResult(env, errCode);
247     }
248     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeGetArgbPixels success.");
249     return getJsResult(env, IMAGE_SUCCESS);
250 }
251 
TestNativeGetColorSpaceNative(napi_env env, napi_callback_info info)252 static napi_value TestNativeGetColorSpaceNative(napi_env env, napi_callback_info info)
253 {
254     OH_PixelmapNative *pixelmap = nullptr;
255     OH_NativeColorSpaceManager *getColorSpaceNative = nullptr;
256     Image_ErrorCode errCode = OH_PixelmapNative_GetColorSpaceNative(pixelmap, &getColorSpaceNative);
257     if (errCode != IMAGE_BAD_PARAMETER) {
258         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_GetColorSpaceNative failed, errCode: %{public}d.", errCode);
259         return getJsResult(env, errCode);
260     }
261     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeGetColorSpaceNative success.");
262     return getJsResult(env, IMAGE_SUCCESS);
263 }
264 
TestNativeSetColorSpaceNative(napi_env env, napi_callback_info info)265 static napi_value TestNativeSetColorSpaceNative(napi_env env, napi_callback_info info)
266 {
267     OH_PixelmapNative *pixelmap = nullptr;
268     OH_NativeColorSpaceManager *setColorSpaceNative = nullptr;
269     Image_ErrorCode errCode = OH_PixelmapNative_SetColorSpaceNative(pixelmap, setColorSpaceNative);
270     if (errCode != IMAGE_BAD_PARAMETER) {
271         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_SetColorSpaceNative failed, errCode: %{public}d.", errCode);
272         return getJsResult(env, errCode);
273     }
274     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeSetColorSpaceNative success.");
275     return getJsResult(env, IMAGE_SUCCESS);
276 }
277 
TestNativeSetGetSrcPixelFormat(napi_env env, napi_callback_info info)278 static napi_value TestNativeSetGetSrcPixelFormat(napi_env env, napi_callback_info info)
279 {
280     OH_Pixelmap_InitializationOptions *ops = nullptr;
281     OH_PixelmapInitializationOptions_Create(&ops);
282     int32_t srcpixelFormat = 0;
283     OH_PixelmapInitializationOptions_SetSrcPixelFormat(ops, 1);
284     OH_PixelmapInitializationOptions_GetSrcPixelFormat(ops, &srcpixelFormat);
285     Image_ErrorCode errCode = OH_PixelmapInitializationOptions_Release(ops);
286     if (errCode != IMAGE_BAD_PARAMETER) {
287         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_SetGetSrcPixelFormat failed, errCode: %{public}d.", errCode);
288         return getJsResult(env, errCode);
289     }
290     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeSetGetSrcPixelFormat success.");
291     return getJsResult(env, IMAGE_SUCCESS);
292 }
293 
TestNativeCreateEmptyPixelmap(napi_env env, napi_callback_info info)294 static napi_value TestNativeCreateEmptyPixelmap(napi_env env, napi_callback_info info)
295 {
296     OH_Pixelmap_InitializationOptions *options = nullptr;
297     OH_PixelmapNative **pixelmap = nullptr;
298     Image_ErrorCode errCode = OH_PixelmapNative_CreateEmptyPixelmap(options, pixelmap);
299     if (errCode != IMAGE_BAD_PARAMETER) {
300         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_CreateEmptyPixelmap failed, errCode: %{public}d.", errCode);
301         return getJsResult(env, errCode);
302     }
303     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeCreateEmptyPixelmap success.");
304     return getJsResult(env, IMAGE_SUCCESS);
305 }
306 
TestNativeConvertAlphaFormat(napi_env env, napi_callback_info info)307 static napi_value TestNativeConvertAlphaFormat(napi_env env, napi_callback_info info)
308 {
309     OH_PixelmapNative* srcpixelmap = nullptr;
310     OH_PixelmapNative* dstpixelmap = nullptr;
311     const bool isPremul = false;
312     Image_ErrorCode errCode = OH_PixelmapNative_ConvertAlphaFormat(srcpixelmap, dstpixelmap, isPremul);
313     if (errCode != IMAGE_BAD_PARAMETER) {
314         OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_ConvertAlphaFormat failed, errCode: %{public}d.", errCode);
315         return getJsResult(env, errCode);
316     }
317     OH_LOG_INFO(LOG_APP, "ImagePixelmapNativeCTest TestNativeConvertAlphaFormat success.");
318     return getJsResult(env, IMAGE_SUCCESS);
319 }
320 
setInt32NamedProperty(napi_env env, napi_value object, const char *utf8name, uint32_t value)321 static void setInt32NamedProperty(napi_env env, napi_value object, const char *utf8name, uint32_t value)
322 {
323     napi_value tmp;
324     napi_create_int32(env, value, &tmp);
325     napi_set_named_property(env, object, utf8name, tmp);
326 }
327 
CheckVpe()328 static bool CheckVpe()
329 {
330     void* handle = dlopen(VPE_SO_NAME, RTLD_LAZY);
331     if (handle == nullptr) {
332         OH_LOG_INFO(LOG_APP, "CheckVpe failed");
333         return false;
334     }
335     dlclose(handle);
336     handle = nullptr;
337     return true;
338 }
339 
340 EXTERN_C_START
Init(napi_env env, napi_value exports)341 static napi_value Init(napi_env env, napi_value exports)
342 {
343     napi_property_descriptor desc[] = {
344         {"testCreatePixelMapWithStrideAbnormal", nullptr, TestCreatePixelMapWithStrideAbnormal, nullptr, nullptr,
345          nullptr, napi_default, nullptr},
346         {"testInitializationOptionsSetRowStrideNormal", nullptr, TestInitializationOptionsSetRowStrideNormal, nullptr,
347          nullptr, nullptr, napi_default, nullptr},
348         {"testNativeScaleWithAntiAliasingAbnormal", nullptr, TestNativeScaleWithAntiAliasingAbnormal, nullptr, nullptr,
349          nullptr, napi_default, nullptr},
350         {"testScaleWithAntiAliasingAbnormal", nullptr, TestScaleWithAntiAliasingAbnormal, nullptr, nullptr,
351          nullptr, napi_default, nullptr},
352         {"testNativeGetNativeBufferAbnormal", nullptr, TestNativeGetNativeBufferAbnormal, nullptr, nullptr,
353          nullptr, napi_default, nullptr},
354         {"testNativeSetMetaDataNull", nullptr, TestNativeSetMetaDataNull, nullptr, nullptr,
355          nullptr, napi_default, nullptr},
356         {"testNativeSetMemoryName", nullptr, TestNativeSetMemoryName, nullptr, nullptr,
357          nullptr, napi_default, nullptr},
358         {"testNativeGetArgbPixels", nullptr, TestNativeGetArgbPixels, nullptr, nullptr,
359          nullptr, napi_default, nullptr},
360         {"testNativeGetColorSpaceNative", nullptr, TestNativeGetColorSpaceNative, nullptr, nullptr,
361          nullptr, napi_default, nullptr},
362         {"testNativeSetColorSpaceNative", nullptr, TestNativeSetColorSpaceNative, nullptr, nullptr,
363          nullptr, napi_default, nullptr},
364         {"testNativeGetMetaDataNull", nullptr, TestNativeGetMetaDataNull, nullptr, nullptr,
365          nullptr, napi_default, nullptr},
366         {"testNativeSetGetSrcPixelFormat", nullptr, TestNativeSetGetSrcPixelFormat, nullptr, nullptr,
367          nullptr, napi_default, nullptr},
368         {"testNativeCreateEmptyPixelmap", nullptr, TestNativeCreateEmptyPixelmap, nullptr,
369          nullptr, nullptr, napi_default, nullptr},
370         {"testNativeConvertAlphaFormat", nullptr, TestNativeConvertAlphaFormat, nullptr, nullptr,
371          nullptr, napi_default, nullptr},
372     };
373     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
374     return exports;
375 }
376 EXTERN_C_END
377 
378 static napi_module demoModule = {
379     .nm_version = 1,
380     .nm_flags = 0,
381     .nm_filename = nullptr,
382     .nm_register_func = Init,
383     .nm_modname = "entry",
384     .nm_priv = ((void *)0),
385     .reserved = {0},
386 };
387 
RegisterEntryModule(void)388 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }