• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdio>
17 #include <climits>
18 #include <memory>
19 #include <string>
20 #include "rawfile/raw_file.h"
21 #include "napi/native_api.h"
22 #include "multimedia/image_framework/image/image_packer_native.h"
23 
24 #define MIMETYPE_JPEG_STRING "image/jpeg"
25 #define MIMETYPE_PNG_STRING "image/png"
26 #define MIMETYPE_WEBP_STRING "image/webp"
27 
28 constexpr int32_t NUM_0 = 0;
29 constexpr int32_t NUM_1 = 1;
30 constexpr int32_t NUM_2 = 2;
31 constexpr int32_t NUM_3 = 3;
32 constexpr int32_t NUM_4 = 4;
33 
34 constexpr uint32_t QUALITY = 100;
35 constexpr uint64_t DEFAULT_BUFFER_SIZE = 25 * 1024 * 1024;
36 
CreatePacker()37 static std::shared_ptr<OH_ImagePackerNative> CreatePacker()
38 {
39     OH_ImagePackerNative *packer = nullptr;
40     if (OH_ImagePackerNative_Create(&packer) != IMAGE_SUCCESS) {
41         return nullptr;
42     }
43     std::shared_ptr<OH_ImagePackerNative> ptr(packer, OH_ImagePackerNative_Release);
44     return ptr;
45 }
46 
CreatePackingOpts(const char * mimeTypeStr)47 static std::shared_ptr<OH_PackingOptions> CreatePackingOpts(const char* mimeTypeStr)
48 {
49     OH_PackingOptions *opts = nullptr;
50     if (OH_PackingOptions_Create(&opts) != IMAGE_SUCCESS) {
51         return nullptr;
52     }
53 
54     Image_MimeType mimeType;
55     mimeType.size = strlen(mimeTypeStr);
56     mimeType.data = (char*)mimeTypeStr;
57     if (OH_PackingOptions_SetMimeType(opts, &mimeType) != IMAGE_SUCCESS) {
58         OH_PackingOptions_Release(opts);
59         return nullptr;
60     }
61 
62     if (OH_PackingOptions_SetQuality(opts, QUALITY) != IMAGE_SUCCESS) {
63         OH_PackingOptions_Release(opts);
64         return nullptr;
65     }
66 
67     std::shared_ptr<OH_PackingOptions> ptr(opts, OH_PackingOptions_Release);
68     return ptr;
69 }
70 
CreatePixelMap(OH_ImageSourceNative * imgSource)71 static std::shared_ptr<OH_PixelmapNative> CreatePixelMap(OH_ImageSourceNative* imgSource)
72 {
73     OH_DecodingOptions *decOpts = nullptr;
74     if (OH_DecodingOptions_Create(&decOpts) != IMAGE_SUCCESS) {
75         return nullptr;
76     }
77 
78     OH_PixelmapNative *pixelMap = nullptr;
79     if (OH_ImageSourceNative_CreatePixelmap(imgSource, decOpts, &pixelMap) != IMAGE_SUCCESS) {
80         OH_DecodingOptions_Release(decOpts);
81         return nullptr;
82     }
83 
84     OH_DecodingOptions_Release(decOpts);
85     std::shared_ptr<OH_PixelmapNative> ptr(pixelMap, OH_PixelmapNative_Release);
86     return ptr;
87 }
88 
WriteFile(const char * outPath,uint8_t * outBuffer,size_t outBufferSize)89 static bool WriteFile(const char* outPath, uint8_t* outBuffer, size_t outBufferSize)
90 {
91     FILE* file = fopen(outPath, "w");
92     if (file == nullptr) {
93         return false;
94     }
95 
96     if (fwrite(outBuffer, sizeof(uint8_t), outBufferSize, file) <= 0) {
97         return false;
98     }
99 
100     if (fclose(file) != 0) {
101         return false;
102     }
103     return true;
104 }
105 
106 // PixelMap转为data
packToDataPixelMap(napi_env env,napi_callback_info info)107 static napi_value packToDataPixelMap(napi_env env, napi_callback_info info)
108 {
109     napi_value retSucess = nullptr;
110     napi_create_int32(env, 0, &retSucess);
111     napi_value retFailed = nullptr;
112     napi_create_int32(env, -1, &retFailed);
113     size_t argCount = NUM_2;
114     napi_value argValue[NUM_2] = {0};
115     size_t dataSize;
116     void* inBuffer;
117     char outPath[PATH_MAX];
118     size_t outPathLen = 0;
119     if (napi_get_cb_info(env, info, &argCount, argValue, nullptr, nullptr) != napi_ok || argCount < NUM_2) {
120         return retFailed;
121     }
122     napi_get_arraybuffer_info(env, argValue[NUM_0], &inBuffer, &dataSize);
123     napi_get_value_string_utf8(env, argValue[NUM_1], outPath, PATH_MAX, &outPathLen);
124     auto ptrPacker = CreatePacker();
125     if (!ptrPacker) {
126         return retFailed;
127     }
128     auto ptrOpts = CreatePackingOpts(MIMETYPE_JPEG_STRING);
129     if (!ptrOpts) {
130         return retFailed;
131     }
132     OH_ImageSourceNative *imgSource = nullptr;
133     Image_ErrorCode errCode = OH_ImageSourceNative_CreateFromData(
134         (uint8_t*)inBuffer, dataSize, &imgSource);
135     if (errCode != IMAGE_SUCCESS) {
136         return retFailed;
137     }
138     std::shared_ptr<OH_ImageSourceNative> ptrImgSource(imgSource, OH_ImageSourceNative_Release);
139     auto ptrPixelMap = CreatePixelMap(ptrImgSource.get());
140     if (!ptrPixelMap) {
141         return retFailed;
142     }
143     uint8_t* outBuffer = new uint8_t[DEFAULT_BUFFER_SIZE];
144     size_t outBufferSize = 0;
145     errCode = OH_ImagePackerNative_PackToDataFromPixelmap(
146         ptrPacker.get(), ptrOpts.get(), ptrPixelMap.get(), outBuffer, &outBufferSize);
147     if (errCode != IMAGE_SUCCESS) {
148         delete [] outBuffer;
149         return retFailed;
150     }
151     if (!WriteFile(outPath, outBuffer, outBufferSize)) {
152         delete [] outBuffer;
153         return retFailed;
154     }
155     delete [] outBuffer;
156     return retSucess;
157 }
158 
159 // PixelMap转为file
packPixelMapToFile(napi_env env,napi_callback_info info)160 static napi_value packPixelMapToFile(napi_env env, napi_callback_info info)
161 {
162     napi_value retSucess = nullptr;
163     napi_create_int32(env, 0, &retSucess);
164     napi_value retFailed = nullptr;
165     napi_create_int32(env, -1, &retFailed);
166 
167     size_t argCount = NUM_2;
168     napi_value argValue[NUM_2] = {0};
169     char inPath[PATH_MAX];
170     size_t inPathLen = 0;
171     int32_t outFD;
172 
173     if (napi_get_cb_info(env, info, &argCount, argValue, nullptr, nullptr) != napi_ok || argCount < NUM_2) {
174         return retFailed;
175     }
176     napi_get_value_string_utf8(env, argValue[NUM_0], inPath, PATH_MAX, &inPathLen);
177     napi_get_value_int32(env, argValue[NUM_1], &outFD);
178 
179     auto ptrPacker = CreatePacker();
180     if (!ptrPacker) {
181         return retFailed;
182     }
183 
184     auto ptrOpts = CreatePackingOpts(MIMETYPE_PNG_STRING);
185     if (!ptrOpts) {
186         return retFailed;
187     }
188 
189     OH_ImageSourceNative *imgSource = nullptr;
190     Image_ErrorCode errCode = OH_ImageSourceNative_CreateFromUri(inPath, inPathLen, &imgSource);
191     if (errCode != IMAGE_SUCCESS) {
192         return retFailed;
193     }
194     std::shared_ptr<OH_ImageSourceNative> ptrImgSource(imgSource, OH_ImageSourceNative_Release);
195 
196     auto ptrPixelMap = CreatePixelMap(ptrImgSource.get());
197     if (!ptrPixelMap) {
198         return retFailed;
199     }
200 
201     errCode = OH_ImagePackerNative_PackToFileFromPixelmap(
202         ptrPacker.get(), ptrOpts.get(), ptrPixelMap.get(), outFD);
203     if (errCode != IMAGE_SUCCESS) {
204         return retFailed;
205     }
206     return retSucess;
207 }
208 
209 // ImageSource转为file
packToFileImageSource(napi_env env,napi_callback_info info)210 static napi_value packToFileImageSource(napi_env env, napi_callback_info info)
211 {
212     napi_value retSucess = nullptr;
213     napi_create_int32(env, 0, &retSucess);
214     napi_value retFailed = nullptr;
215     napi_create_int32(env, -1, &retFailed);
216 
217     size_t argCount = NUM_2;
218     napi_value argValue[NUM_2] = {0};
219     int32_t inFD;
220     int32_t outFD;
221 
222     if (napi_get_cb_info(env, info, &argCount, argValue, nullptr, nullptr) != napi_ok || argCount < NUM_2) {
223         return retFailed;
224     }
225     napi_get_value_int32(env, argValue[NUM_0], &inFD);
226     napi_get_value_int32(env, argValue[NUM_1], &outFD);
227 
228     auto ptrPacker = CreatePacker();
229     if (!ptrPacker) {
230         return retFailed;
231     }
232 
233     auto ptrOpts = CreatePackingOpts(MIMETYPE_JPEG_STRING);
234     if (!ptrOpts) {
235         return retFailed;
236     }
237 
238     OH_ImageSourceNative *imgSource = nullptr;
239     Image_ErrorCode errCode = OH_ImageSourceNative_CreateFromFd(inFD, &imgSource);
240     if (errCode != IMAGE_SUCCESS) {
241         return retFailed;
242     }
243     std::shared_ptr<OH_ImageSourceNative> ptrImgSource(imgSource, OH_ImageSourceNative_Release);
244 
245     errCode = OH_ImagePackerNative_PackToFileFromImageSource(
246         ptrPacker.get(), ptrOpts.get(), imgSource, outFD);
247     if (errCode != IMAGE_SUCCESS) {
248         return retFailed;
249     }
250     return retSucess;
251 }
252 
253 // ImageSource转为data
packToDataImageSource(napi_env env,napi_callback_info info)254 static napi_value packToDataImageSource(napi_env env, napi_callback_info info)
255 {
256     napi_value retSucess = nullptr;
257     napi_create_int32(env, 0, &retSucess);
258     napi_value retFailed = nullptr;
259     napi_create_int32(env, -1, &retFailed);
260     size_t argCount = NUM_4;
261     napi_value argValue[NUM_4] = {0};
262     RawFileDescriptor rawSrc;
263     int64_t tmp;
264     char outPath[PATH_MAX];
265     size_t outPathLen = 0;
266     if (napi_get_cb_info(env, info, &argCount, argValue, nullptr, nullptr) != napi_ok || argCount < NUM_4) {
267         return retFailed;
268     }
269     napi_get_value_int32(env, argValue[NUM_0], &rawSrc.fd);
270     napi_get_value_int64(env, argValue[NUM_1], &tmp);
271     rawSrc.start = static_cast<long>(tmp);
272     napi_get_value_int64(env, argValue[NUM_2], &tmp);
273     rawSrc.length = static_cast<long>(tmp);
274     napi_get_value_string_utf8(env, argValue[NUM_3], outPath, PATH_MAX, &outPathLen);
275     auto ptrPacker = CreatePacker();
276     auto ptrOpts = CreatePackingOpts(MIMETYPE_WEBP_STRING);
277     if (!ptrPacker || !ptrOpts) {
278         return retFailed;
279     }
280     OH_ImageSourceNative *imgSource = nullptr;
281     Image_ErrorCode errCode = OH_ImageSourceNative_CreateFromRawFile(&rawSrc, &imgSource);
282     if (errCode != IMAGE_SUCCESS) {
283         return retFailed;
284     }
285     std::shared_ptr<OH_ImageSourceNative> ptrImgSource(imgSource, OH_ImageSourceNative_Release);
286 
287     uint8_t* outBuffer = new uint8_t[DEFAULT_BUFFER_SIZE];
288     size_t outBufferSize = 0;
289     errCode = OH_ImagePackerNative_PackToDataFromImageSource(
290         ptrPacker.get(), ptrOpts.get(), imgSource, outBuffer, &outBufferSize);
291     if (errCode != IMAGE_SUCCESS) {
292         delete [] outBuffer;
293         return retFailed;
294     }
295     if (!WriteFile(outPath, outBuffer, outBufferSize)) {
296         delete [] outBuffer;
297         return retFailed;
298     }
299     delete [] outBuffer;
300     return retSucess;
301 }
302 
Init(napi_env env,napi_value exports)303 EXTERN_C_START static napi_value Init(napi_env env, napi_value exports)
304 {
305     napi_property_descriptor desc[] = {
306         {"packToDataPixelMap", nullptr, packToDataPixelMap, nullptr, nullptr, nullptr, napi_default, nullptr},
307         {"packPixelMapToFile", nullptr, packPixelMapToFile, nullptr, nullptr, nullptr, napi_default, nullptr},
308         {"packToFileImageSource", nullptr, packToFileImageSource, nullptr, nullptr, nullptr, napi_default, nullptr},
309         {"packToDataImageSource", nullptr, packToDataImageSource, nullptr, nullptr, nullptr, napi_default, nullptr},
310     };
311 
312     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[NUM_0]), desc);
313     return exports;
314 }
315 EXTERN_C_END
316 
317 static napi_module demoModule = {
318     .nm_version = 1,
319     .nm_flags = 0,
320     .nm_filename = nullptr,
321     .nm_register_func = Init,
322     .nm_modname = "entry",
323     .nm_priv = ((void *)0),
324     .reserved = {0},
325 };
326 
RegisterEntryModule(void)327 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
328