1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "image_packer_native.h"
17
18 #include "common_utils.h"
19 #include "image_packer.h"
20 #include "image_packer_native_impl.h"
21 #include "image_source_native_impl.h"
22 #include "pixelmap_native_impl.h"
23 #ifndef _WIN32
24 #include "securec.h"
25 #else
26 #include "memory.h"
27 #endif
28
29 using namespace OHOS;
30 using namespace Media;
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 constexpr size_t SIZE_ZERO = 0;
36 constexpr int32_t IMAGE_BASE = 62980096;
37 static constexpr int32_t IMAGE_BASE_19 = 19;
38 static constexpr int32_t IMAGE_BASE_16 = 16;
39 static constexpr int32_t IMAGE_BASE_17 = 17;
40 static constexpr int32_t IMAGE_BASE_26 = 26;
41 static constexpr int32_t IMAGE_BASE_31 = 31;
42 static constexpr int32_t IMAGE_BASE_152 = 152;
43 static constexpr int32_t IMAGE_BASE_27 = 27;
44 static constexpr int32_t IMAGE_BASE_12 = 12;
45 static constexpr int32_t IMAGE_BASE_13 = 13;
46 static constexpr int32_t IMAGE_BASE_6 = 6;
47 static constexpr int32_t IMAGE_BASE_14 = 14;
48 static constexpr int32_t IMAGE_BASE_4 = 4;
49 static constexpr int32_t IMAGE_BASE_9 = 9;
50 static constexpr int32_t IMAGE_BASE_20 = 20;
51 static constexpr int32_t IMAGE_BASE_22 = 22;
52 static constexpr int32_t IMAGE_BASE_23 = 23;
53
54 struct OH_PackingOptions {
55 Image_MimeType mimeType;
56 int quality;
57 int32_t desiredDynamicRange = IMAGE_PACKER_DYNAMIC_RANGE_SDR;
58 uint16_t loop;
59 uint16_t* delayTimes;
60 uint32_t delayTimesSize;
61 uint16_t* disposalTypes;
62 uint32_t disposalTypesSize;
63 bool needsPackProperties = false;
64 };
65
ToNewErrorCode(int code)66 static Image_ErrorCode ToNewErrorCode(int code)
67 {
68 switch (code) {
69 case 0:
70 return IMAGE_SUCCESS;
71 case IMAGE_BASE + IMAGE_BASE_19:
72 return IMAGE_BAD_PARAMETER;
73 case IMAGE_BASE + IMAGE_BASE_16:
74 case IMAGE_BASE + IMAGE_BASE_17:
75 case IMAGE_BASE + IMAGE_BASE_26:
76 return IMAGE_UNKNOWN_MIME_TYPE;
77 case IMAGE_BASE + IMAGE_BASE_31:
78 return IMAGE_TOO_LARGE;
79 case IMAGE_BASE + IMAGE_BASE_152:
80 return IMAGE_UNSUPPORTED_OPERATION;
81 case IMAGE_BASE + IMAGE_BASE_27:
82 return IMAGE_UNSUPPORTED_METADATA;
83 case IMAGE_BASE + IMAGE_BASE_12:
84 return IMAGE_UNSUPPORTED_CONVERSION;
85 case IMAGE_BASE + IMAGE_BASE_13:
86 return IMAGE_INVALID_REGION;
87 case IMAGE_BASE + IMAGE_BASE_6:
88 return IMAGE_ALLOC_FAILED;
89 case IMAGE_BASE + IMAGE_BASE_14:
90 return IMAGE_BAD_SOURCE;
91 case IMAGE_BASE + IMAGE_BASE_4:
92 case IMAGE_BASE + IMAGE_BASE_9:
93 case IMAGE_BASE + IMAGE_BASE_20:
94 case IMAGE_BASE + IMAGE_BASE_22:
95 return IMAGE_DECODE_FAILED;
96 case IMAGE_BASE + IMAGE_BASE_23:
97 return IMAGE_ENCODE_FAILED;
98 default:
99 return IMAGE_UNKNOWN_ERROR;
100 }
101 };
102
ParseDynamicRange(int32_t val)103 static EncodeDynamicRange ParseDynamicRange(int32_t val)
104 {
105 if (val <= static_cast<int32_t>(EncodeDynamicRange::SDR)) {
106 return EncodeDynamicRange(val);
107 }
108
109 return EncodeDynamicRange::SDR;
110 }
111
CopyPackingOptions(const OH_PackingOptions * options,PackOption & packOption)112 static Image_ErrorCode CopyPackingOptions(const OH_PackingOptions *options, PackOption &packOption)
113 {
114 if (options == nullptr) {
115 return IMAGE_BAD_PARAMETER;
116 }
117
118 std::string format(options->mimeType.data, options->mimeType.size);
119 if (format.empty()) {
120 return IMAGE_BAD_PARAMETER;
121 }
122 packOption.format = format;
123 packOption.quality = options->quality;
124 packOption.needsPackProperties = options->needsPackProperties;
125 packOption.desiredDynamicRange = ParseDynamicRange(options->desiredDynamicRange);
126 return IMAGE_SUCCESS;
127 }
128
129 MIDK_EXPORT
OH_PackingOptions_Create(OH_PackingOptions ** options)130 Image_ErrorCode OH_PackingOptions_Create(OH_PackingOptions **options)
131 {
132 *options = new OH_PackingOptions();
133 if (*options == nullptr) {
134 return IMAGE_BAD_PARAMETER;
135 }
136 return IMAGE_SUCCESS;
137 }
138
139 MIDK_EXPORT
OH_PackingOptions_GetMimeType(OH_PackingOptions * options,Image_MimeType * format)140 Image_ErrorCode OH_PackingOptions_GetMimeType(OH_PackingOptions *options,
141 Image_MimeType *format)
142 {
143 if (options == nullptr || format == nullptr) {
144 return IMAGE_BAD_PARAMETER;
145 }
146
147 if (format->size != SIZE_ZERO && format->size < options->mimeType.size) {
148 return IMAGE_BAD_PARAMETER;
149 }
150
151 format->size = (format->size == SIZE_ZERO) ? options->mimeType.size : format->size;
152 format->data = static_cast<char *>(malloc(format->size));
153 if (format->data == nullptr) {
154 return IMAGE_ALLOC_FAILED;
155 }
156
157 if (memcpy_s(format->data, format->size, options->mimeType.data, options->mimeType.size) != 0) {
158 free(format->data);
159 format->data = nullptr;
160 format->size = 0;
161 return IMAGE_COPY_FAILED;
162 }
163 return IMAGE_SUCCESS;
164 }
165
166 MIDK_EXPORT
OH_PackingOptions_SetMimeType(OH_PackingOptions * options,Image_MimeType * format)167 Image_ErrorCode OH_PackingOptions_SetMimeType(OH_PackingOptions *options,
168 Image_MimeType *format)
169 {
170 if (options == nullptr || format->data == nullptr || format->size == 0) {
171 return IMAGE_BAD_PARAMETER;
172 }
173 if (options->mimeType.data != nullptr) {
174 free(options->mimeType.data);
175 options->mimeType.data = nullptr;
176 }
177 options->mimeType.size = format->size;
178 options->mimeType.data = static_cast<char *>(malloc(options->mimeType.size));
179 if (options->mimeType.data == nullptr) {
180 return IMAGE_ALLOC_FAILED;
181 }
182 if (memcpy_s(options->mimeType.data, options->mimeType.size, format->data, format->size) != 0) {
183 free(options->mimeType.data);
184 options->mimeType.data = nullptr;
185 options->mimeType.size = 0;
186 return IMAGE_COPY_FAILED;
187 }
188 return IMAGE_SUCCESS;
189 }
190
191 MIDK_EXPORT
OH_PackingOptions_GetQuality(OH_PackingOptions * options,uint32_t * quality)192 Image_ErrorCode OH_PackingOptions_GetQuality(OH_PackingOptions *options, uint32_t *quality)
193 {
194 if (options == nullptr || quality == nullptr) {
195 return IMAGE_BAD_PARAMETER;
196 }
197 *quality = options->quality;
198 return IMAGE_SUCCESS;
199 }
200
201 MIDK_EXPORT
OH_PackingOptions_SetQuality(OH_PackingOptions * options,uint32_t quality)202 Image_ErrorCode OH_PackingOptions_SetQuality(OH_PackingOptions *options, uint32_t quality)
203 {
204 if (options == nullptr) {
205 return IMAGE_BAD_PARAMETER;
206 }
207 options->quality = static_cast<int>(quality);
208 return IMAGE_SUCCESS;
209 }
210
211 MIDK_EXPORT
OH_PackingOptions_GetNeedsPackProperties(OH_PackingOptions * options,bool * needsPackProperties)212 Image_ErrorCode OH_PackingOptions_GetNeedsPackProperties(OH_PackingOptions *options, bool *needsPackProperties)
213 {
214 if (options == nullptr || needsPackProperties == nullptr) {
215 return IMAGE_BAD_PARAMETER;
216 }
217 *needsPackProperties = options->needsPackProperties;
218 return IMAGE_SUCCESS;
219 }
220
221 MIDK_EXPORT
OH_PackingOptions_SetNeedsPackProperties(OH_PackingOptions * options,bool needsPackProperties)222 Image_ErrorCode OH_PackingOptions_SetNeedsPackProperties(OH_PackingOptions *options, bool needsPackProperties)
223 {
224 if (options == nullptr) {
225 return IMAGE_BAD_PARAMETER;
226 }
227 options->needsPackProperties = needsPackProperties;
228 return IMAGE_SUCCESS;
229 }
230
231 MIDK_EXPORT
OH_PackingOptions_GetDesiredDynamicRange(OH_PackingOptions * options,int32_t * desiredDynamicRange)232 Image_ErrorCode OH_PackingOptions_GetDesiredDynamicRange(OH_PackingOptions *options, int32_t* desiredDynamicRange)
233 {
234 if (options == nullptr || desiredDynamicRange == nullptr) {
235 return IMAGE_BAD_PARAMETER;
236 }
237 *desiredDynamicRange = options->desiredDynamicRange;
238 return IMAGE_SUCCESS;
239 }
240
241 MIDK_EXPORT
OH_PackingOptions_SetDesiredDynamicRange(OH_PackingOptions * options,int32_t desiredDynamicRange)242 Image_ErrorCode OH_PackingOptions_SetDesiredDynamicRange(OH_PackingOptions *options, int32_t desiredDynamicRange)
243 {
244 if (options == nullptr) {
245 return IMAGE_BAD_PARAMETER;
246 }
247 options->desiredDynamicRange = desiredDynamicRange;
248 return IMAGE_SUCCESS;
249 }
250
251 MIDK_EXPORT
OH_PackingOptions_SetLoop(OH_PackingOptions * options,uint16_t loop)252 Image_ErrorCode OH_PackingOptions_SetLoop(OH_PackingOptions *options, uint16_t loop)
253 {
254 if (options == nullptr) {
255 return IMAGE_BAD_PARAMETER;
256 }
257 options->loop = loop;
258 return IMAGE_SUCCESS;
259 }
260
261 MIDK_EXPORT
OH_PackingOptions_GetLoop(OH_PackingOptions * options,uint16_t * loop)262 Image_ErrorCode OH_PackingOptions_GetLoop(OH_PackingOptions *options, uint16_t* loop)
263 {
264 if (options == nullptr || loop == nullptr) {
265 return IMAGE_BAD_PARAMETER;
266 }
267 *loop = options->loop;
268 return IMAGE_SUCCESS;
269 }
270
271 MIDK_EXPORT
OH_PackingOptions_SetDelayTimes(OH_PackingOptions * options,uint16_t * delayTimes,uint32_t delayTimesSize)272 Image_ErrorCode OH_PackingOptions_SetDelayTimes(OH_PackingOptions *options, uint16_t* delayTimes,
273 uint32_t delayTimesSize)
274 {
275 if (options == nullptr) {
276 return IMAGE_BAD_PARAMETER;
277 }
278 options->delayTimes = delayTimes;
279 options->delayTimesSize = delayTimesSize;
280 return IMAGE_SUCCESS;
281 }
282
283 MIDK_EXPORT
OH_PackingOptions_GetDelayTimes(OH_PackingOptions * options,uint16_t * delayTimes,uint32_t * delayTimesSize)284 Image_ErrorCode OH_PackingOptions_GetDelayTimes(OH_PackingOptions *options, uint16_t* delayTimes,
285 uint32_t* delayTimesSize)
286 {
287 if (options == nullptr || delayTimes == nullptr || delayTimesSize == nullptr) {
288 return IMAGE_BAD_PARAMETER;
289 }
290 delayTimes = options->delayTimes;
291 *delayTimesSize = options->delayTimesSize;
292 return IMAGE_SUCCESS;
293 }
294
295 MIDK_EXPORT
OH_PackingOptions_SetDisposalTypes(OH_PackingOptions * options,uint16_t * disposalTypes,uint32_t disposalTypesSize)296 Image_ErrorCode OH_PackingOptions_SetDisposalTypes(OH_PackingOptions *options, uint16_t* disposalTypes,
297 uint32_t disposalTypesSize)
298 {
299 if (options == nullptr) {
300 return IMAGE_BAD_PARAMETER;
301 }
302 options->disposalTypes = disposalTypes;
303 options->disposalTypesSize = disposalTypesSize;
304 return IMAGE_SUCCESS;
305 }
306
307 MIDK_EXPORT
OH_PackingOptions_GetDisposalTypes(OH_PackingOptions * options,uint16_t * disposalTypes,uint32_t * disposalTypesSize)308 Image_ErrorCode OH_PackingOptions_GetDisposalTypes(OH_PackingOptions *options, uint16_t* disposalTypes,
309 uint32_t* disposalTypesSize)
310 {
311 if (options == nullptr || disposalTypes == nullptr || disposalTypesSize == nullptr) {
312 return IMAGE_BAD_PARAMETER;
313 }
314 disposalTypes = options->disposalTypes;
315 *disposalTypesSize = options->disposalTypesSize;
316 return IMAGE_SUCCESS;
317 }
318
319 MIDK_EXPORT
OH_PackingOptions_Release(OH_PackingOptions * options)320 Image_ErrorCode OH_PackingOptions_Release(OH_PackingOptions *options)
321 {
322 if (options == nullptr) {
323 return IMAGE_BAD_PARAMETER;
324 }
325 if (options->mimeType.data) {
326 free(options->mimeType.data);
327 options->mimeType.data = nullptr;
328 }
329 delete options;
330 return IMAGE_SUCCESS;
331 }
332
333 MIDK_EXPORT
OH_ImagePackerNative_Create(OH_ImagePackerNative ** imagePacker)334 Image_ErrorCode OH_ImagePackerNative_Create(OH_ImagePackerNative **imagePacker)
335 {
336 auto imagePacker2 = new OH_ImagePackerNative();
337 if (imagePacker2 == nullptr || imagePacker2->GetInnerImagePacker() == nullptr) {
338 if (imagePacker2) {
339 delete imagePacker2;
340 }
341 return IMAGE_BAD_PARAMETER;
342 }
343 *imagePacker = imagePacker2;
344 return IMAGE_SUCCESS;
345 }
346
347 MIDK_EXPORT
OH_ImagePackerNative_PackToDataFromImageSource(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_ImageSourceNative * imageSource,uint8_t * outData,size_t * size)348 Image_ErrorCode OH_ImagePackerNative_PackToDataFromImageSource(OH_ImagePackerNative *imagePacker,
349 OH_PackingOptions *options, OH_ImageSourceNative *imageSource, uint8_t *outData, size_t *size)
350 {
351 if (imagePacker == nullptr || options == nullptr || imageSource == nullptr || outData == nullptr) {
352 return IMAGE_BAD_PARAMETER;
353 }
354
355 PackOption packOption;
356 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
357 if (errorCode != IMAGE_SUCCESS) {
358 return errorCode;
359 }
360 return ToNewErrorCode(imagePacker->PackingFromImageSource(&packOption, imageSource,
361 outData, reinterpret_cast<int64_t*>(size)));
362 }
363
364 MIDK_EXPORT
OH_ImagePackerNative_PackToDataFromPixelmap(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PixelmapNative * pixelmap,uint8_t * outData,size_t * size)365 Image_ErrorCode OH_ImagePackerNative_PackToDataFromPixelmap(OH_ImagePackerNative *imagePacker,
366 OH_PackingOptions *options, OH_PixelmapNative *pixelmap, uint8_t *outData, size_t *size)
367 {
368 if (imagePacker == nullptr || options == nullptr || pixelmap == nullptr || outData == nullptr) {
369 return IMAGE_BAD_PARAMETER;
370 }
371
372 PackOption packOption;
373 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
374 if (errorCode != IMAGE_SUCCESS) {
375 return errorCode;
376 }
377 return ToNewErrorCode(imagePacker->PackingFromPixelmap(&packOption, pixelmap, outData,
378 reinterpret_cast<int64_t*>(size)));
379 }
380
381 MIDK_EXPORT
OH_ImagePackerNative_PackToDataFromPicture(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PictureNative * picture,uint8_t * outData,size_t * size)382 Image_ErrorCode OH_ImagePackerNative_PackToDataFromPicture(OH_ImagePackerNative *imagePacker,
383 OH_PackingOptions *options, OH_PictureNative *picture, uint8_t *outData, size_t *size)
384 {
385 if (imagePacker == nullptr || options == nullptr || picture == nullptr || outData == nullptr) {
386 return IMAGE_BAD_PARAMETER;
387 }
388
389 PackOption packOption;
390 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
391 if (errorCode != IMAGE_SUCCESS) {
392 return errorCode;
393 }
394 return ToNewErrorCode(imagePacker->PackToDataFromPicture(&packOption, picture, outData,
395 reinterpret_cast<int64_t*>(size)));
396 }
397
398 MIDK_EXPORT
OH_ImagePackerNative_PackToFileFromImageSource(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_ImageSourceNative * imageSource,int32_t fd)399 Image_ErrorCode OH_ImagePackerNative_PackToFileFromImageSource(OH_ImagePackerNative *imagePacker,
400 OH_PackingOptions *options, OH_ImageSourceNative *imageSource, int32_t fd)
401 {
402 if (imagePacker == nullptr || options == nullptr || imageSource == nullptr) {
403 return IMAGE_BAD_PARAMETER;
404 }
405
406 PackOption packOption;
407 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
408 if (errorCode != IMAGE_SUCCESS) {
409 return errorCode;
410 }
411 return ToNewErrorCode(imagePacker->PackToFileFromImageSource(&packOption, imageSource, fd));
412 }
413
414 MIDK_EXPORT
OH_ImagePackerNative_PackToFileFromPixelmap(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PixelmapNative * pixelmap,int32_t fd)415 Image_ErrorCode OH_ImagePackerNative_PackToFileFromPixelmap(OH_ImagePackerNative *imagePacker,
416 OH_PackingOptions *options, OH_PixelmapNative *pixelmap, int32_t fd)
417 {
418 if (imagePacker == nullptr || options == nullptr || pixelmap == nullptr) {
419 return IMAGE_BAD_PARAMETER;
420 }
421
422 PackOption packOption;
423 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
424 if (errorCode != IMAGE_SUCCESS) {
425 return errorCode;
426 }
427 return ToNewErrorCode(imagePacker->PackToFileFromPixelmap(&packOption, pixelmap, fd));
428 }
429
430 MIDK_EXPORT
OH_ImagePackerNative_PackToFileFromPicture(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PictureNative * picture,int32_t fd)431 Image_ErrorCode OH_ImagePackerNative_PackToFileFromPicture(OH_ImagePackerNative *imagePacker,
432 OH_PackingOptions *options, OH_PictureNative *picture, int32_t fd)
433 {
434 if (imagePacker == nullptr || options == nullptr || picture == nullptr) {
435 return IMAGE_BAD_PARAMETER;
436 }
437
438 PackOption packOption;
439 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
440 if (errorCode != IMAGE_SUCCESS) {
441 return errorCode;
442 }
443 return ToNewErrorCode(imagePacker->PackToFileFromPicture(&packOption, picture, fd));
444 }
445
446 MIDK_EXPORT
OH_ImagePackerNative_Release(OH_ImagePackerNative * imagePacker)447 Image_ErrorCode OH_ImagePackerNative_Release(OH_ImagePackerNative *imagePacker)
448 {
449 if (imagePacker == nullptr) {
450 return IMAGE_BAD_PARAMETER;
451 }
452 delete imagePacker;
453 return IMAGE_SUCCESS;
454 }
455
456 #ifdef __cplusplus
457 };
458 #endif