• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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