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_log.h"
20 #include "image_packer.h"
21 #include "image_packer_native_impl.h"
22 #include "image_source_native_impl.h"
23 #include "media_errors.h"
24 #include "pixelmap_native_impl.h"
25 #ifndef _WIN32
26 #include "securec.h"
27 #else
28 #include "memory.h"
29 #endif
30
31 using namespace OHOS;
32 using namespace Media;
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 constexpr size_t SIZE_ZERO = 0;
38 constexpr int32_t IMAGE_BASE = 62980096;
39 constexpr int32_t MASK_2 = 0x3;
40 constexpr int32_t MASK_16 = 0xffff;
41 static constexpr int32_t IMAGE_BASE_19 = 19;
42 static constexpr int32_t IMAGE_BASE_16 = 16;
43 static constexpr int32_t IMAGE_BASE_17 = 17;
44 static constexpr int32_t IMAGE_BASE_26 = 26;
45 static constexpr int32_t IMAGE_BASE_31 = 31;
46 static constexpr int32_t IMAGE_BASE_152 = 152;
47 static constexpr int32_t IMAGE_BASE_27 = 27;
48 static constexpr int32_t IMAGE_BASE_12 = 12;
49 static constexpr int32_t IMAGE_BASE_13 = 13;
50 static constexpr int32_t IMAGE_BASE_6 = 6;
51 static constexpr int32_t IMAGE_BASE_14 = 14;
52 static constexpr int32_t IMAGE_BASE_4 = 4;
53 static constexpr int32_t IMAGE_BASE_9 = 9;
54 static constexpr int32_t IMAGE_BASE_20 = 20;
55 static constexpr int32_t IMAGE_BASE_22 = 22;
56 static constexpr int32_t IMAGE_BASE_23 = 23;
57 static Image_MimeType *IMAGE_PACKER_SUPPORTED_FORMATS = nullptr;
58 static size_t SUPPORTED_FORMATS_SIZE = 0;
59
60 struct OH_PackingOptions {
61 Image_MimeType mimeType;
62 int quality;
63 int32_t desiredDynamicRange = IMAGE_PACKER_DYNAMIC_RANGE_SDR;
64 uint16_t loop;
65 uint16_t* delayTimes;
66 uint32_t delayTimesSize;
67 uint16_t* disposalTypes;
68 uint32_t disposalTypesSize;
69 bool needsPackProperties = false;
70 };
71
72 struct OH_PackingOptionsForSequence {
73 int32_t frameCount;
74 int32_t* delayTimeList;
75 size_t delayTimeListLength;
76 uint32_t* disposalTypes;
77 size_t disposalTypesLength;
78 uint32_t loopCount = 1;
79 };
80
ToNewErrorCode(int code)81 static Image_ErrorCode ToNewErrorCode(int code)
82 {
83 switch (code) {
84 case 0:
85 return IMAGE_SUCCESS;
86 case IMAGE_BASE + IMAGE_BASE_19:
87 return IMAGE_BAD_PARAMETER;
88 case IMAGE_BASE + IMAGE_BASE_16:
89 case IMAGE_BASE + IMAGE_BASE_17:
90 case IMAGE_BASE + IMAGE_BASE_26:
91 return IMAGE_UNKNOWN_MIME_TYPE;
92 case IMAGE_BASE + IMAGE_BASE_31:
93 return IMAGE_TOO_LARGE;
94 case IMAGE_BASE + IMAGE_BASE_152:
95 return IMAGE_UNSUPPORTED_OPERATION;
96 case IMAGE_BASE + IMAGE_BASE_27:
97 return IMAGE_UNSUPPORTED_METADATA;
98 case IMAGE_BASE + IMAGE_BASE_12:
99 return IMAGE_UNSUPPORTED_CONVERSION;
100 case IMAGE_BASE + IMAGE_BASE_13:
101 return IMAGE_INVALID_REGION;
102 case IMAGE_BASE + IMAGE_BASE_6:
103 return IMAGE_ALLOC_FAILED;
104 case IMAGE_BASE + IMAGE_BASE_14:
105 return IMAGE_BAD_SOURCE;
106 case IMAGE_BASE + IMAGE_BASE_4:
107 case IMAGE_BASE + IMAGE_BASE_9:
108 case IMAGE_BASE + IMAGE_BASE_20:
109 case IMAGE_BASE + IMAGE_BASE_22:
110 return IMAGE_DECODE_FAILED;
111 case IMAGE_BASE + IMAGE_BASE_23:
112 return IMAGE_ENCODE_FAILED;
113 default:
114 return IMAGE_UNKNOWN_ERROR;
115 }
116 };
117
ParseDynamicRange(int32_t val)118 static EncodeDynamicRange ParseDynamicRange(int32_t val)
119 {
120 if (val <= static_cast<int32_t>(EncodeDynamicRange::SDR)) {
121 return EncodeDynamicRange(val);
122 }
123
124 return EncodeDynamicRange::SDR;
125 }
126
CopyPackingOptions(const OH_PackingOptions * options,PackOption & packOption)127 static Image_ErrorCode CopyPackingOptions(const OH_PackingOptions *options, PackOption &packOption)
128 {
129 if (options == nullptr) {
130 return IMAGE_BAD_PARAMETER;
131 }
132
133 std::string format(options->mimeType.data, options->mimeType.size);
134 if (format.empty()) {
135 return IMAGE_BAD_PARAMETER;
136 }
137 packOption.format = format;
138 packOption.quality = options->quality;
139 packOption.needsPackProperties = options->needsPackProperties;
140 packOption.desiredDynamicRange = ParseDynamicRange(options->desiredDynamicRange);
141 return IMAGE_SUCCESS;
142 }
143
144 MIDK_EXPORT
OH_PackingOptions_Create(OH_PackingOptions ** options)145 Image_ErrorCode OH_PackingOptions_Create(OH_PackingOptions **options)
146 {
147 *options = new OH_PackingOptions();
148 if (*options == nullptr) {
149 return IMAGE_BAD_PARAMETER;
150 }
151 return IMAGE_SUCCESS;
152 }
153
154 MIDK_EXPORT
OH_PackingOptions_GetMimeType(OH_PackingOptions * options,Image_MimeType * format)155 Image_ErrorCode OH_PackingOptions_GetMimeType(OH_PackingOptions *options,
156 Image_MimeType *format)
157 {
158 if (options == nullptr || format == nullptr) {
159 return IMAGE_BAD_PARAMETER;
160 }
161
162 if (format->size != SIZE_ZERO && format->size < options->mimeType.size) {
163 return IMAGE_BAD_PARAMETER;
164 }
165
166 format->size = (format->size == SIZE_ZERO) ? options->mimeType.size : format->size;
167 format->data = static_cast<char *>(malloc(format->size));
168 if (format->data == nullptr) {
169 return IMAGE_ALLOC_FAILED;
170 }
171
172 if (memcpy_s(format->data, format->size, options->mimeType.data, options->mimeType.size) != 0) {
173 free(format->data);
174 format->data = nullptr;
175 format->size = 0;
176 return IMAGE_COPY_FAILED;
177 }
178 return IMAGE_SUCCESS;
179 }
180
181 MIDK_EXPORT
OH_PackingOptions_GetMimeTypeWithNull(OH_PackingOptions * options,Image_MimeType * format)182 Image_ErrorCode OH_PackingOptions_GetMimeTypeWithNull(OH_PackingOptions *options,
183 Image_MimeType *format)
184 {
185 if (options == nullptr || format == nullptr) {
186 return IMAGE_PACKER_INVALID_PARAMETER;
187 }
188
189 if (format->size != SIZE_ZERO && format->size < options->mimeType.size) {
190 return IMAGE_PACKER_INVALID_PARAMETER;
191 }
192
193 char* buffer = static_cast<char*>(malloc(options->mimeType.size + 1));
194 if (buffer == nullptr) {
195 return IMAGE_PACKER_INVALID_PARAMETER;
196 }
197
198 if (memcpy_s(buffer, options->mimeType.size + 1, options->mimeType.data, options->mimeType.size) != EOK) {
199 free(buffer);
200 return IMAGE_PACKER_INVALID_PARAMETER;
201 }
202
203 buffer[options->mimeType.size] = '\0';
204
205 format->data = buffer;
206 format->size = options->mimeType.size;
207
208 return IMAGE_SUCCESS;
209 }
210
211 MIDK_EXPORT
OH_PackingOptions_SetMimeType(OH_PackingOptions * options,Image_MimeType * format)212 Image_ErrorCode OH_PackingOptions_SetMimeType(OH_PackingOptions *options,
213 Image_MimeType *format)
214 {
215 if (options == nullptr || format->data == nullptr || format->size == 0) {
216 return IMAGE_BAD_PARAMETER;
217 }
218 if (options->mimeType.data != nullptr) {
219 free(options->mimeType.data);
220 options->mimeType.data = nullptr;
221 }
222 options->mimeType.size = format->size;
223 options->mimeType.data = static_cast<char *>(malloc(options->mimeType.size));
224 if (options->mimeType.data == nullptr) {
225 return IMAGE_ALLOC_FAILED;
226 }
227 if (memcpy_s(options->mimeType.data, options->mimeType.size, format->data, format->size) != 0) {
228 free(options->mimeType.data);
229 options->mimeType.data = nullptr;
230 options->mimeType.size = 0;
231 return IMAGE_COPY_FAILED;
232 }
233 return IMAGE_SUCCESS;
234 }
235
236 MIDK_EXPORT
OH_PackingOptions_GetQuality(OH_PackingOptions * options,uint32_t * quality)237 Image_ErrorCode OH_PackingOptions_GetQuality(OH_PackingOptions *options, uint32_t *quality)
238 {
239 if (options == nullptr || quality == nullptr) {
240 return IMAGE_BAD_PARAMETER;
241 }
242 *quality = options->quality;
243 return IMAGE_SUCCESS;
244 }
245
246 MIDK_EXPORT
OH_PackingOptions_SetQuality(OH_PackingOptions * options,uint32_t quality)247 Image_ErrorCode OH_PackingOptions_SetQuality(OH_PackingOptions *options, uint32_t quality)
248 {
249 if (options == nullptr) {
250 return IMAGE_BAD_PARAMETER;
251 }
252 options->quality = static_cast<int>(quality);
253 return IMAGE_SUCCESS;
254 }
255
256 MIDK_EXPORT
OH_PackingOptions_GetNeedsPackProperties(OH_PackingOptions * options,bool * needsPackProperties)257 Image_ErrorCode OH_PackingOptions_GetNeedsPackProperties(OH_PackingOptions *options, bool *needsPackProperties)
258 {
259 if (options == nullptr || needsPackProperties == nullptr) {
260 return IMAGE_BAD_PARAMETER;
261 }
262 *needsPackProperties = options->needsPackProperties;
263 return IMAGE_SUCCESS;
264 }
265
266 MIDK_EXPORT
OH_PackingOptions_SetNeedsPackProperties(OH_PackingOptions * options,bool needsPackProperties)267 Image_ErrorCode OH_PackingOptions_SetNeedsPackProperties(OH_PackingOptions *options, bool needsPackProperties)
268 {
269 if (options == nullptr) {
270 return IMAGE_BAD_PARAMETER;
271 }
272 options->needsPackProperties = needsPackProperties;
273 return IMAGE_SUCCESS;
274 }
275
276 MIDK_EXPORT
OH_PackingOptions_GetDesiredDynamicRange(OH_PackingOptions * options,int32_t * desiredDynamicRange)277 Image_ErrorCode OH_PackingOptions_GetDesiredDynamicRange(OH_PackingOptions *options, int32_t* desiredDynamicRange)
278 {
279 if (options == nullptr || desiredDynamicRange == nullptr) {
280 return IMAGE_BAD_PARAMETER;
281 }
282 *desiredDynamicRange = options->desiredDynamicRange;
283 return IMAGE_SUCCESS;
284 }
285
286 MIDK_EXPORT
OH_PackingOptions_SetDesiredDynamicRange(OH_PackingOptions * options,int32_t desiredDynamicRange)287 Image_ErrorCode OH_PackingOptions_SetDesiredDynamicRange(OH_PackingOptions *options, int32_t desiredDynamicRange)
288 {
289 if (options == nullptr) {
290 return IMAGE_BAD_PARAMETER;
291 }
292 options->desiredDynamicRange = desiredDynamicRange;
293 return IMAGE_SUCCESS;
294 }
295
296 MIDK_EXPORT
OH_PackingOptions_SetLoop(OH_PackingOptions * options,uint16_t loop)297 Image_ErrorCode OH_PackingOptions_SetLoop(OH_PackingOptions *options, uint16_t loop)
298 {
299 if (options == nullptr) {
300 return IMAGE_BAD_PARAMETER;
301 }
302 options->loop = loop;
303 return IMAGE_SUCCESS;
304 }
305
306 MIDK_EXPORT
OH_PackingOptions_GetLoop(OH_PackingOptions * options,uint16_t * loop)307 Image_ErrorCode OH_PackingOptions_GetLoop(OH_PackingOptions *options, uint16_t* loop)
308 {
309 if (options == nullptr || loop == nullptr) {
310 return IMAGE_BAD_PARAMETER;
311 }
312 *loop = options->loop;
313 return IMAGE_SUCCESS;
314 }
315
316 MIDK_EXPORT
OH_PackingOptions_SetDelayTimes(OH_PackingOptions * options,uint16_t * delayTimes,uint32_t delayTimesSize)317 Image_ErrorCode OH_PackingOptions_SetDelayTimes(OH_PackingOptions *options, uint16_t* delayTimes,
318 uint32_t delayTimesSize)
319 {
320 if (options == nullptr) {
321 return IMAGE_BAD_PARAMETER;
322 }
323 options->delayTimes = delayTimes;
324 options->delayTimesSize = delayTimesSize;
325 return IMAGE_SUCCESS;
326 }
327
328 MIDK_EXPORT
OH_PackingOptions_GetDelayTimes(OH_PackingOptions * options,uint16_t * delayTimes,uint32_t * delayTimesSize)329 Image_ErrorCode OH_PackingOptions_GetDelayTimes(OH_PackingOptions *options, uint16_t* delayTimes,
330 uint32_t* delayTimesSize)
331 {
332 if (options == nullptr || delayTimes == nullptr || delayTimesSize == nullptr) {
333 return IMAGE_BAD_PARAMETER;
334 }
335 delayTimes = options->delayTimes;
336 *delayTimesSize = options->delayTimesSize;
337 return IMAGE_SUCCESS;
338 }
339
340 MIDK_EXPORT
OH_PackingOptions_SetDisposalTypes(OH_PackingOptions * options,uint16_t * disposalTypes,uint32_t disposalTypesSize)341 Image_ErrorCode OH_PackingOptions_SetDisposalTypes(OH_PackingOptions *options, uint16_t* disposalTypes,
342 uint32_t disposalTypesSize)
343 {
344 if (options == nullptr) {
345 return IMAGE_BAD_PARAMETER;
346 }
347 options->disposalTypes = disposalTypes;
348 options->disposalTypesSize = disposalTypesSize;
349 return IMAGE_SUCCESS;
350 }
351
352 MIDK_EXPORT
OH_PackingOptions_GetDisposalTypes(OH_PackingOptions * options,uint16_t * disposalTypes,uint32_t * disposalTypesSize)353 Image_ErrorCode OH_PackingOptions_GetDisposalTypes(OH_PackingOptions *options, uint16_t* disposalTypes,
354 uint32_t* disposalTypesSize)
355 {
356 if (options == nullptr || disposalTypes == nullptr || disposalTypesSize == nullptr) {
357 return IMAGE_BAD_PARAMETER;
358 }
359 disposalTypes = options->disposalTypes;
360 *disposalTypesSize = options->disposalTypesSize;
361 return IMAGE_SUCCESS;
362 }
363
364 MIDK_EXPORT
OH_PackingOptions_Release(OH_PackingOptions * options)365 Image_ErrorCode OH_PackingOptions_Release(OH_PackingOptions *options)
366 {
367 if (options == nullptr) {
368 return IMAGE_BAD_PARAMETER;
369 }
370 if (options->mimeType.data) {
371 free(options->mimeType.data);
372 options->mimeType.data = nullptr;
373 }
374 delete options;
375 return IMAGE_SUCCESS;
376 }
377
378 MIDK_EXPORT
OH_PackingOptionsForSequence_Create(OH_PackingOptionsForSequence ** options)379 Image_ErrorCode OH_PackingOptionsForSequence_Create(OH_PackingOptionsForSequence **options)
380 {
381 *options = new OH_PackingOptionsForSequence();
382 if (*options == nullptr) {
383 return IMAGE_BAD_PARAMETER;
384 }
385 return IMAGE_SUCCESS;
386 }
387
388 MIDK_EXPORT
OH_PackingOptionsForSequence_SetFrameCount(OH_PackingOptionsForSequence * options,uint32_t frameCount)389 Image_ErrorCode OH_PackingOptionsForSequence_SetFrameCount(OH_PackingOptionsForSequence *options,
390 uint32_t frameCount)
391 {
392 if (options == nullptr) {
393 return IMAGE_BAD_PARAMETER;
394 }
395 options->frameCount = static_cast<int32_t>(frameCount);
396 return IMAGE_SUCCESS;
397 }
398
399 MIDK_EXPORT
OH_PackingOptionsForSequence_GetFrameCount(OH_PackingOptionsForSequence * options,uint32_t * frameCount)400 Image_ErrorCode OH_PackingOptionsForSequence_GetFrameCount(OH_PackingOptionsForSequence *options,
401 uint32_t *frameCount)
402 {
403 if (options == nullptr || frameCount == nullptr) {
404 return IMAGE_BAD_PARAMETER;
405 }
406 *frameCount = static_cast<uint32_t>(options->frameCount);
407 return IMAGE_SUCCESS;
408 }
409
410 MIDK_EXPORT
OH_PackingOptionsForSequence_SetDelayTimeList(OH_PackingOptionsForSequence * options,int32_t * delayTimeList,size_t delayTimeListLength)411 Image_ErrorCode OH_PackingOptionsForSequence_SetDelayTimeList(OH_PackingOptionsForSequence *options,
412 int32_t *delayTimeList, size_t delayTimeListLength)
413 {
414 if (options == nullptr) {
415 return IMAGE_BAD_PARAMETER;
416 }
417 options->delayTimeList = delayTimeList;
418 options->delayTimeListLength = delayTimeListLength;
419 return IMAGE_SUCCESS;
420 }
421
422 MIDK_EXPORT
OH_PackingOptionsForSequence_GetDelayTimeList(OH_PackingOptionsForSequence * options,int32_t * delayTimeList,size_t delayTimeListLength)423 Image_ErrorCode OH_PackingOptionsForSequence_GetDelayTimeList(OH_PackingOptionsForSequence *options,
424 int32_t *delayTimeList, size_t delayTimeListLength)
425 {
426 if (options == nullptr || delayTimeList == nullptr || delayTimeListLength == 0) {
427 return IMAGE_BAD_PARAMETER;
428 }
429 size_t minDelayTimeListLength = std::min(delayTimeListLength, options->delayTimeListLength);
430 if (memcpy_s(delayTimeList, delayTimeListLength * sizeof(int32_t),
431 options->delayTimeList, minDelayTimeListLength * sizeof(int32_t)) != 0) {
432 return IMAGE_COPY_FAILED;
433 }
434 return IMAGE_SUCCESS;
435 }
436
437 MIDK_EXPORT
OH_PackingOptionsForSequence_SetDisposalTypes(OH_PackingOptionsForSequence * options,uint32_t * disposalTypes,size_t disposalTypesLength)438 Image_ErrorCode OH_PackingOptionsForSequence_SetDisposalTypes(OH_PackingOptionsForSequence *options,
439 uint32_t *disposalTypes, size_t disposalTypesLength)
440 {
441 if (options == nullptr) {
442 return IMAGE_BAD_PARAMETER;
443 }
444 options->disposalTypes = disposalTypes;
445 options->disposalTypesLength = disposalTypesLength;
446 return IMAGE_SUCCESS;
447 }
448
449 MIDK_EXPORT
OH_PackingOptionsForSequence_GetDisposalTypes(OH_PackingOptionsForSequence * options,uint32_t * disposalTypes,size_t disposalTypesLength)450 Image_ErrorCode OH_PackingOptionsForSequence_GetDisposalTypes(OH_PackingOptionsForSequence *options,
451 uint32_t *disposalTypes, size_t disposalTypesLength)
452 {
453 if (options == nullptr || disposalTypes == nullptr || disposalTypesLength == 0) {
454 return IMAGE_BAD_PARAMETER;
455 }
456 size_t minDisposalTypesLength = std::min(disposalTypesLength, options->disposalTypesLength);
457 if (memcpy_s(disposalTypes, disposalTypesLength * sizeof(uint32_t),
458 options->disposalTypes, minDisposalTypesLength * sizeof(uint32_t)) != 0) {
459 return IMAGE_COPY_FAILED;
460 }
461 return IMAGE_SUCCESS;
462 }
463
464 MIDK_EXPORT
OH_PackingOptionsForSequence_SetLoopCount(OH_PackingOptionsForSequence * options,uint32_t loopCount)465 Image_ErrorCode OH_PackingOptionsForSequence_SetLoopCount(OH_PackingOptionsForSequence *options, uint32_t loopCount)
466 {
467 if (options == nullptr) {
468 return IMAGE_BAD_PARAMETER;
469 }
470 options->loopCount = loopCount;
471 return IMAGE_SUCCESS;
472 }
473
474 MIDK_EXPORT
OH_PackingOptionsForSequence_GetLoopCount(OH_PackingOptionsForSequence * options,uint32_t * loopCount)475 Image_ErrorCode OH_PackingOptionsForSequence_GetLoopCount(OH_PackingOptionsForSequence *options, uint32_t *loopCount)
476 {
477 if (options == nullptr || loopCount == nullptr) {
478 return IMAGE_BAD_PARAMETER;
479 }
480 *loopCount = options->loopCount;
481 return IMAGE_SUCCESS;
482 }
483
484 MIDK_EXPORT
OH_PackingOptionsForSequence_Release(OH_PackingOptionsForSequence * options)485 Image_ErrorCode OH_PackingOptionsForSequence_Release(OH_PackingOptionsForSequence *options)
486 {
487 if (options == nullptr) {
488 return IMAGE_BAD_PARAMETER;
489 }
490 delete options;
491 return IMAGE_SUCCESS;
492 }
493
494 MIDK_EXPORT
OH_ImagePackerNative_Create(OH_ImagePackerNative ** imagePacker)495 Image_ErrorCode OH_ImagePackerNative_Create(OH_ImagePackerNative **imagePacker)
496 {
497 auto imagePacker2 = new OH_ImagePackerNative();
498 if (imagePacker2 == nullptr || imagePacker2->GetInnerImagePacker() == nullptr) {
499 if (imagePacker2) {
500 delete imagePacker2;
501 }
502 return IMAGE_BAD_PARAMETER;
503 }
504 *imagePacker = imagePacker2;
505 return IMAGE_SUCCESS;
506 }
507
508 MIDK_EXPORT
OH_ImagePackerNative_PackToDataFromImageSource(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_ImageSourceNative * imageSource,uint8_t * outData,size_t * size)509 Image_ErrorCode OH_ImagePackerNative_PackToDataFromImageSource(OH_ImagePackerNative *imagePacker,
510 OH_PackingOptions *options, OH_ImageSourceNative *imageSource, uint8_t *outData, size_t *size)
511 {
512 if (imagePacker == nullptr || options == nullptr || imageSource == nullptr || outData == nullptr) {
513 return IMAGE_BAD_PARAMETER;
514 }
515
516 PackOption packOption;
517 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
518 if (errorCode != IMAGE_SUCCESS) {
519 return errorCode;
520 }
521 return ToNewErrorCode(imagePacker->PackingFromImageSource(&packOption, imageSource,
522 outData, reinterpret_cast<int64_t*>(size)));
523 }
524
525 MIDK_EXPORT
OH_ImagePackerNative_PackToDataFromPixelmap(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PixelmapNative * pixelmap,uint8_t * outData,size_t * size)526 Image_ErrorCode OH_ImagePackerNative_PackToDataFromPixelmap(OH_ImagePackerNative *imagePacker,
527 OH_PackingOptions *options, OH_PixelmapNative *pixelmap, uint8_t *outData, size_t *size)
528 {
529 if (imagePacker == nullptr || options == nullptr || pixelmap == nullptr || outData == nullptr) {
530 return IMAGE_BAD_PARAMETER;
531 }
532
533 PackOption packOption;
534 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
535 if (errorCode != IMAGE_SUCCESS) {
536 return errorCode;
537 }
538 return ToNewErrorCode(imagePacker->PackingFromPixelmap(&packOption, pixelmap, outData,
539 reinterpret_cast<int64_t*>(size)));
540 }
541
542 MIDK_EXPORT
OH_ImagePackerNative_PackToDataFromPicture(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PictureNative * picture,uint8_t * outData,size_t * size)543 Image_ErrorCode OH_ImagePackerNative_PackToDataFromPicture(OH_ImagePackerNative *imagePacker,
544 OH_PackingOptions *options, OH_PictureNative *picture, uint8_t *outData, size_t *size)
545 {
546 if (imagePacker == nullptr || options == nullptr || picture == nullptr || outData == nullptr) {
547 return IMAGE_BAD_PARAMETER;
548 }
549
550 PackOption packOption;
551 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
552 if (errorCode != IMAGE_SUCCESS) {
553 return errorCode;
554 }
555 return ToNewErrorCode(imagePacker->PackToDataFromPicture(&packOption, picture, outData,
556 reinterpret_cast<int64_t*>(size)));
557 }
558
559 MIDK_EXPORT
OH_ImagePackerNative_PackToFileFromImageSource(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_ImageSourceNative * imageSource,int32_t fd)560 Image_ErrorCode OH_ImagePackerNative_PackToFileFromImageSource(OH_ImagePackerNative *imagePacker,
561 OH_PackingOptions *options, OH_ImageSourceNative *imageSource, int32_t fd)
562 {
563 if (imagePacker == nullptr || options == nullptr || imageSource == nullptr) {
564 return IMAGE_BAD_PARAMETER;
565 }
566
567 PackOption packOption;
568 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
569 if (errorCode != IMAGE_SUCCESS) {
570 return errorCode;
571 }
572 return ToNewErrorCode(imagePacker->PackToFileFromImageSource(&packOption, imageSource, fd));
573 }
574
575 MIDK_EXPORT
OH_ImagePackerNative_PackToFileFromPixelmap(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PixelmapNative * pixelmap,int32_t fd)576 Image_ErrorCode OH_ImagePackerNative_PackToFileFromPixelmap(OH_ImagePackerNative *imagePacker,
577 OH_PackingOptions *options, OH_PixelmapNative *pixelmap, int32_t fd)
578 {
579 if (imagePacker == nullptr || options == nullptr || pixelmap == nullptr) {
580 return IMAGE_BAD_PARAMETER;
581 }
582
583 PackOption packOption;
584 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
585 if (errorCode != IMAGE_SUCCESS) {
586 return errorCode;
587 }
588 return ToNewErrorCode(imagePacker->PackToFileFromPixelmap(&packOption, pixelmap, fd));
589 }
590
591 MIDK_EXPORT
OH_ImagePackerNative_PackToFileFromPicture(OH_ImagePackerNative * imagePacker,OH_PackingOptions * options,OH_PictureNative * picture,int32_t fd)592 Image_ErrorCode OH_ImagePackerNative_PackToFileFromPicture(OH_ImagePackerNative *imagePacker,
593 OH_PackingOptions *options, OH_PictureNative *picture, int32_t fd)
594 {
595 if (imagePacker == nullptr || options == nullptr || picture == nullptr) {
596 return IMAGE_BAD_PARAMETER;
597 }
598
599 PackOption packOption;
600 Image_ErrorCode errorCode = CopyPackingOptions(options, packOption);
601 if (errorCode != IMAGE_SUCCESS) {
602 return errorCode;
603 }
604 return ToNewErrorCode(imagePacker->PackToFileFromPicture(&packOption, picture, fd));
605 }
606
HandlePackingOptionsForSequence(OH_PackingOptionsForSequence * options,PackOption * packOption)607 static bool HandlePackingOptionsForSequence(OH_PackingOptionsForSequence *options, PackOption *packOption)
608 {
609 packOption->format = "image/gif";
610 packOption->loop = static_cast<uint16_t>(options->loopCount & MASK_16);
611 for (uint32_t i = 0; i < options->delayTimeListLength; i++) {
612 if (options->delayTimeList[i] <= 0 || options->delayTimeList[i] > MASK_16) {
613 return false;
614 }
615 packOption->delayTimes.push_back(
616 static_cast<uint16_t>(options->delayTimeList[i]) & static_cast<uint16_t>(MASK_16));
617 }
618 if (options->delayTimeListLength < static_cast<size_t>(options->frameCount)) {
619 for (size_t i = options->delayTimeListLength; i < static_cast<size_t>(options->frameCount); i++) {
620 packOption->delayTimes.push_back(
621 static_cast<uint16_t>(options->delayTimeList[options->delayTimeListLength - 1]) &
622 static_cast<uint16_t>(MASK_16));
623 }
624 }
625 for (uint32_t i = 0; i < options->disposalTypesLength; i++) {
626 if (options->disposalTypes[i] > MASK_2) {
627 return false;
628 }
629 packOption->disposalTypes.push_back(options->disposalTypes[i] & MASK_2);
630 }
631 return true;
632 }
633
634 MIDK_EXPORT
OH_ImagePackerNative_PackToDataFromPixelmapSequence(OH_ImagePackerNative * imagePacker,OH_PackingOptionsForSequence * options,OH_PixelmapNative ** pixelmapSequence,size_t sequenceLength,uint8_t * outData,size_t * outDataSize)635 Image_ErrorCode OH_ImagePackerNative_PackToDataFromPixelmapSequence(OH_ImagePackerNative *imagePacker,
636 OH_PackingOptionsForSequence *options, OH_PixelmapNative **pixelmapSequence,
637 size_t sequenceLength, uint8_t *outData, size_t *outDataSize)
638 {
639 if (imagePacker == nullptr || options == nullptr || pixelmapSequence == nullptr || outData == nullptr ||
640 options->delayTimeListLength == 0 || sequenceLength == 0 || options->loopCount > MASK_16 ||
641 options->frameCount <= 0) {
642 return IMAGE_BAD_PARAMETER;
643 }
644 std::vector<OH_PixelmapNative*> pixelmaps;
645 PackOption packOption;
646 if (!HandlePackingOptionsForSequence(options, &packOption)) {
647 return IMAGE_BAD_PARAMETER;
648 }
649 if (sequenceLength >= static_cast<size_t>(options->frameCount)) {
650 for (int i = 0; i < options->frameCount; i++) {
651 pixelmaps.push_back(pixelmapSequence[i]);
652 }
653 } else {
654 for (size_t i = 0; i < sequenceLength; i++) {
655 pixelmaps.push_back(pixelmapSequence[i]);
656 }
657 for (size_t i = sequenceLength; i < static_cast<size_t>(options->frameCount); i++) {
658 pixelmaps.push_back(pixelmapSequence[sequenceLength - 1]);
659 }
660 }
661 return ToNewErrorCode(imagePacker->PackToDataMultiFrames(&packOption, pixelmaps, outData,
662 reinterpret_cast<int64_t*>(outDataSize)));
663 }
664
665 MIDK_EXPORT
OH_ImagePackerNative_PackToFileFromPixelmapSequence(OH_ImagePackerNative * imagePacker,OH_PackingOptionsForSequence * options,OH_PixelmapNative ** pixelmapSequence,size_t sequenceLength,int32_t fd)666 Image_ErrorCode OH_ImagePackerNative_PackToFileFromPixelmapSequence(OH_ImagePackerNative *imagePacker,
667 OH_PackingOptionsForSequence *options, OH_PixelmapNative **pixelmapSequence, size_t sequenceLength, int32_t fd)
668 {
669 if (imagePacker == nullptr || options == nullptr || pixelmapSequence == nullptr ||
670 options->delayTimeListLength == 0 || sequenceLength == 0 || options->loopCount > MASK_16 ||
671 options->frameCount <= 0) {
672 return IMAGE_BAD_PARAMETER;
673 }
674 std::vector<OH_PixelmapNative*> pixelmaps;
675 PackOption packOption;
676 if (!HandlePackingOptionsForSequence(options, &packOption)) {
677 return IMAGE_BAD_PARAMETER;
678 }
679 if (sequenceLength >= static_cast<size_t>(options->frameCount)) {
680 for (int i = 0; i < options->frameCount; i++) {
681 pixelmaps.push_back(pixelmapSequence[i]);
682 }
683 } else {
684 for (size_t i = 0; i < sequenceLength; i++) {
685 pixelmaps.push_back(pixelmapSequence[i]);
686 }
687 for (size_t i = sequenceLength; i < static_cast<size_t>(options->frameCount); i++) {
688 pixelmaps.push_back(pixelmapSequence[sequenceLength - 1]);
689 }
690 }
691 return ToNewErrorCode(imagePacker->PackToFileMultiFrames(&packOption, pixelmaps, fd));
692 }
693
694 MIDK_EXPORT
OH_ImagePackerNative_Release(OH_ImagePackerNative * imagePacker)695 Image_ErrorCode OH_ImagePackerNative_Release(OH_ImagePackerNative *imagePacker)
696 {
697 if (imagePacker == nullptr) {
698 return IMAGE_BAD_PARAMETER;
699 }
700 delete imagePacker;
701 return IMAGE_SUCCESS;
702 }
703
704 MIDK_EXPORT
OH_ImagePackerNative_GetSupportedFormats(Image_MimeType ** supportedFormat,size_t * length)705 Image_ErrorCode OH_ImagePackerNative_GetSupportedFormats(Image_MimeType** supportedFormat, size_t* length)
706 {
707 if (supportedFormat == nullptr || length == nullptr) {
708 return IMAGE_PACKER_INVALID_PARAMETER;
709 }
710 if (IMAGE_PACKER_SUPPORTED_FORMATS != nullptr || SUPPORTED_FORMATS_SIZE != 0) {
711 *supportedFormat = IMAGE_PACKER_SUPPORTED_FORMATS;
712 *length = SUPPORTED_FORMATS_SIZE;
713 return IMAGE_SUCCESS;
714 }
715 std::set<std::string> formats;
716 ImagePacker::GetSupportedFormats(formats);
717
718 *length = formats.size();
719 *supportedFormat = new Image_MimeType[formats.size()];
720 size_t count = 0;
721 for (const auto& str : formats) {
722 (*supportedFormat)[count].data = strdup(str.c_str());
723 if ((*supportedFormat)[count].data == nullptr) {
724 IMAGE_LOGE("ImagePacker strdup failed");
725 continue;
726 }
727 (*supportedFormat)[count].size = str.size();
728 count++;
729 }
730 IMAGE_PACKER_SUPPORTED_FORMATS = *supportedFormat;
731 SUPPORTED_FORMATS_SIZE = *length;
732 return IMAGE_SUCCESS;
733 }
734
735 #ifdef __cplusplus
736 };
737 #endif