• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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_common.h"
17 #include "image_log.h"
18 #include "image_packer.h"
19 #include "image_packer_taihe.h"
20 #include "image_source_taihe.h"
21 #include "image_taihe_utils.h"
22 #include "image_trace.h"
23 #include "picture_taihe.h"
24 #include "pixel_map_taihe.h"
25 #include "media_errors.h"
26 
27 using namespace ANI::Image;
28 
29 namespace {
30     constexpr int32_t INVALID_FD = -1;
31     constexpr int32_t SIZE_256 = 256;
32     constexpr int32_t SIZE_512 = 512;
33     constexpr int32_t SIZE_1024 = 1024;
34     constexpr int32_t SIZE_1440 = 1440;
35     constexpr int32_t SIZE_1920 = 1920;
36     constexpr int64_t FILE_SIZE_300K = 300 * 1024;
37     constexpr int64_t FILE_SIZE_1M = 1 * 1024 * 1024;
38     constexpr int64_t FILE_SIZE_4M = 4 * 1024 * 1024;
39     constexpr int64_t FILE_SIZE_10M = 10 * 1024 * 1024;
40 }
41 
42 namespace ANI::Image {
43 const uint8_t BYTE_FULL = 0xFF;
44 const int32_t SIZE = 100;
45 const int32_t TYPE_IMAGE_SOURCE = 1;
46 const int32_t TYPE_PIXEL_MAP = 2;
47 const int32_t TYPE_PICTURE = 3;
48 const int32_t TYPE_ARRAY = 4;
49 const int64_t DEFAULT_BUFFER_SIZE = 25 * 1024 * 1024; // 25M is the maximum default packedSize
50 
51 struct ImagePackerTaiheContext {
52     OHOS::Media::PackOption packOption;
53     std::shared_ptr<OHOS::Media::ImagePacker> rImagePacker;
54     std::shared_ptr<OHOS::Media::ImageSource> rImageSource;
55     std::shared_ptr<OHOS::Media::PixelMap> rPixelMap;
56 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
57     std::shared_ptr<OHOS::Media::Picture> rPicture;
58 #endif
59     std::shared_ptr<std::vector<std::shared_ptr<OHOS::Media::PixelMap>>> rPixelMaps;
60     std::unique_ptr<uint8_t[]> resultBuffer;
61     int32_t packType = TYPE_IMAGE_SOURCE;
62     int64_t resultBufferSize = 0;
63     int64_t packedSize = 0;
64     int fd = INVALID_FD;
65     bool needReturnErrorCode = true;
66 };
67 
ImagePackerImpl()68 ImagePackerImpl::ImagePackerImpl() : nativeImagePacker_(nullptr) {}
69 
ImagePackerImpl(std::shared_ptr<OHOS::Media::ImagePacker> imagePacker)70 ImagePackerImpl::ImagePackerImpl(std::shared_ptr<OHOS::Media::ImagePacker> imagePacker)
71 {
72     nativeImagePacker_ = imagePacker;
73 }
74 
~ImagePackerImpl()75 ImagePackerImpl::~ImagePackerImpl()
76 {
77     ReleaseSync();
78 }
79 
GetDefaultBufferSize(int32_t width,int32_t height)80 static int64_t GetDefaultBufferSize(int32_t width, int32_t height)
81 {
82     if (width <= SIZE_256 && height <= SIZE_256) {
83         return FILE_SIZE_300K;
84     }
85     if (width <= SIZE_512 && height <= SIZE_512) {
86         return FILE_SIZE_1M;
87     }
88     if (width <= SIZE_1024 && height <= SIZE_1024) {
89         return FILE_SIZE_4M;
90     }
91     if (width <= SIZE_1440 && height <= SIZE_1920) {
92         return FILE_SIZE_10M;
93     }
94     return DEFAULT_BUFFER_SIZE;
95 }
96 
GetDefaultBufferSize(std::unique_ptr<ImagePackerTaiheContext> & context)97 static int64_t GetDefaultBufferSize(std::unique_ptr<ImagePackerTaiheContext> &context)
98 {
99     if (context == nullptr) {
100         return DEFAULT_BUFFER_SIZE;
101     }
102     OHOS::Media::ImageInfo imageInfo {};
103     if (context->packType == TYPE_IMAGE_SOURCE) {
104         if (context->rImageSource == nullptr) {
105             return DEFAULT_BUFFER_SIZE;
106         }
107         context->rImageSource->GetImageInfo(imageInfo);
108     } else if (context->packType == TYPE_PIXEL_MAP) {
109         if (context->rPixelMap == nullptr) {
110             return DEFAULT_BUFFER_SIZE;
111         }
112         context->rPixelMap->GetImageInfo(imageInfo);
113     }
114     if (imageInfo.size.width <= 0 || imageInfo.size.height <= 0) {
115         return DEFAULT_BUFFER_SIZE;
116     }
117     return GetDefaultBufferSize(imageInfo.size.width, imageInfo.size.height);
118 }
119 
ParseDynamicRange(PackingOption const & options)120 static OHOS::Media::EncodeDynamicRange ParseDynamicRange(PackingOption const& options)
121 {
122     uint32_t tmpNumber = 0;
123     if (!options.desiredDynamicRange.has_value()) {
124         return OHOS::Media::EncodeDynamicRange::SDR;
125     } else {
126         tmpNumber = static_cast<uint32_t>(options.desiredDynamicRange->get_value());
127     }
128     if (tmpNumber <= static_cast<uint32_t>(OHOS::Media::EncodeDynamicRange::SDR)) {
129         return OHOS::Media::EncodeDynamicRange(tmpNumber);
130     }
131     return OHOS::Media::EncodeDynamicRange::SDR;
132 }
133 
ParseNeedsPackProperties(PackingOption const & options)134 static bool ParseNeedsPackProperties(PackingOption const& options)
135 {
136     if (!options.needsPackProperties.has_value()) {
137         IMAGE_LOGD("No needsPackProperties in pack option");
138         return false;
139     }
140     return options.needsPackProperties.value();
141 }
142 
ParseBufferSize(std::unique_ptr<ImagePackerTaiheContext> & context,PackingOption const & options)143 static int64_t ParseBufferSize(std::unique_ptr<ImagePackerTaiheContext> &context, PackingOption const& options)
144 {
145     int64_t defaultSize = GetDefaultBufferSize(context);
146     if (!options.bufferSize.has_value()) {
147         IMAGE_LOGI("No bufferSize, Using default");
148         return defaultSize;
149     }
150     int64_t tmpNumber = options.bufferSize.value();
151     IMAGE_LOGD("BufferSize is %{public}" PRId64, tmpNumber);
152     if (tmpNumber < 0) {
153         return defaultSize;
154     }
155     return tmpNumber;
156 }
157 
ParsePackOptionOfQuality(PackingOption const & options)158 static uint8_t ParsePackOptionOfQuality(PackingOption const& options)
159 {
160     uint32_t tmpNumber = options.quality;
161     if (tmpNumber > SIZE) {
162         IMAGE_LOGE("Invalid quality");
163         return BYTE_FULL;
164     } else {
165         return static_cast<uint8_t>(tmpNumber & 0xff);
166     }
167 }
168 
ParsePackOptions(PackingOption const & options)169 static OHOS::Media::PackOption ParsePackOptions(PackingOption const& options)
170 {
171     OHOS::Media::PackOption packOption;
172     packOption.format = std::string(options.format);
173     packOption.quality = ParsePackOptionOfQuality(options);
174     packOption.desiredDynamicRange = ParseDynamicRange(options);
175     IMAGE_LOGI("ParsePackOptions format:[%{public}s]", packOption.format.c_str());
176     packOption.needsPackProperties = ParseNeedsPackProperties(options);
177     return packOption;
178 }
179 
180 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
SetPicture(std::unique_ptr<ImagePackerTaiheContext> & context)181 bool SetPicture(std::unique_ptr<ImagePackerTaiheContext> &context)
182 {
183     IMAGE_LOGD("ImagePacker set picture");
184     if (context->rPicture == nullptr) {
185         ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Picture is nullptr");
186         return false;
187     }
188     context->rImagePacker->AddPicture(*(context->rPicture));
189     return true;
190 }
191 #endif
192 
SetArrayPixel(std::unique_ptr<ImagePackerTaiheContext> & context)193 bool SetArrayPixel(std::unique_ptr<ImagePackerTaiheContext> &context)
194 {
195     IMAGE_LOGD("ImagePacker set pixelmap array");
196     if (!context->rPixelMaps) {
197         ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelmapList is nullptr");
198         return false;
199     }
200     for (auto &pixelMap : *context->rPixelMaps.get()) {
201         context->rImagePacker->AddImage(*(pixelMap.get()));
202     }
203     return true;
204 }
205 
FinalizePackToFile(std::unique_ptr<ImagePackerTaiheContext> & context)206 static bool FinalizePackToFile(std::unique_ptr<ImagePackerTaiheContext> &context)
207 {
208     int64_t packedSize = 0;
209     auto packRes = context->rImagePacker->FinalizePacking(packedSize);
210     IMAGE_LOGD("packRes=%{public}d packedSize=%{public}" PRId64, packRes, packedSize);
211     if (packRes == OHOS::Media::SUCCESS && packedSize > 0) {
212         context->packedSize = packedSize;
213         return true;
214     } else {
215         ImageTaiheUtils::ThrowExceptionError(packRes, "PackedSize outside size");
216         IMAGE_LOGE("Packing failed, packedSize outside size.");
217         if (context->packType == TYPE_PICTURE) {
218             ImageTaiheUtils::ThrowExceptionError(packRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ?
219                 IMAGE_BAD_PARAMETER : IMAGE_ENCODE_FAILED, "PackToFile picture failed");
220         }
221         return false;
222     }
223 }
224 
PackToFileExec(std::unique_ptr<ImagePackerTaiheContext> & context)225 static bool PackToFileExec(std::unique_ptr<ImagePackerTaiheContext> &context)
226 {
227     auto startRes = context->rImagePacker->StartPacking(context->fd, context->packOption);
228     if (startRes != OHOS::Media::SUCCESS) {
229         if (context->packType == TYPE_PICTURE) {
230             ImageTaiheUtils::ThrowExceptionError(startRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ?
231                 IMAGE_BAD_PARAMETER : IMAGE_ENCODE_FAILED, "PackToFile start packing failed");
232             return false;
233         }
234         ImageTaiheUtils::ThrowExceptionError(startRes, "Start packing failed");
235         return false;
236     }
237     if (context->packType == TYPE_IMAGE_SOURCE) {
238         IMAGE_LOGI("ImagePacker set image source");
239         if (!context->rImageSource) {
240             ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "ImageSource is nullptr");
241             return false;
242         }
243         context->rImagePacker->AddImage(*(context->rImageSource));
244     } else if (context->packType == TYPE_PIXEL_MAP) {
245         IMAGE_LOGD("ImagePacker set pixelmap");
246         if (!context->rPixelMap) {
247             ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "Pixelmap is nullptr");
248             return false;
249         }
250         context->rImagePacker->AddImage(*(context->rPixelMap));
251 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
252     } else if (context->packType == TYPE_PICTURE) {
253         if (!SetPicture(context)) {
254             return false;
255         }
256 #endif
257     } else if (context->packType == TYPE_ARRAY) {
258         if (!SetArrayPixel(context)) {
259             return false;
260         }
261     }
262     return FinalizePackToFile(context);
263 }
264 
CheckPackToFileContext(std::unique_ptr<ImagePackerTaiheContext> & context)265 static bool CheckPackToFileContext(std::unique_ptr<ImagePackerTaiheContext> &context)
266 {
267     if (context->rImagePacker == nullptr) {
268         TH_THROW(std::runtime_error, "ImagePacker is nullptr");
269         return false;
270     }
271     if (context->packType == TYPE_IMAGE_SOURCE) {
272         if (context->rImageSource == nullptr) {
273             ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "ImageSource is nullptr");
274             return false;
275         }
276     } else if (context->packType == TYPE_PIXEL_MAP) {
277         if (context->rPixelMap == nullptr) {
278             ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "PixelMap is nullptr");
279             return false;
280         }
281 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
282     } else if (context->packType == TYPE_PICTURE) {
283         if (context->rPicture == nullptr) {
284             ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "Picture is nullptr");
285             return false;
286         }
287 #endif
288     } else if (context->packType == TYPE_ARRAY) {
289         if (context->rPixelMaps == nullptr) {
290             ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "PixelMaps is nullptr");
291             return false;
292         }
293     }
294     if (context->fd <= INVALID_FD) {
295         uint32_t errorCode = ((context->packType == TYPE_PICTURE ||
296             context->packType == TYPE_ARRAY)) ? IMAGE_BAD_PARAMETER : OHOS::Media::ERR_IMAGE_INVALID_PARAMETER;
297         ImageTaiheUtils::ThrowExceptionError(errorCode, "Invaild fd");
298         return false;
299     }
300     return true;
301 }
302 
PackImageSourceToFileSync(weak::ImageSource source,int32_t fd,PackingOption const & options)303 void ImagePackerImpl::PackImageSourceToFileSync(weak::ImageSource source, int32_t fd, PackingOption const& options)
304 {
305     OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackImageSourceToFile");
306 
307     ImageSourceImpl* imageSourceImpl = reinterpret_cast<ImageSourceImpl*>(source->GetImplPtr());
308     if (imageSourceImpl == nullptr) {
309         return;
310     }
311     std::unique_ptr<ImagePackerTaiheContext> taiheContext = std::make_unique<ImagePackerTaiheContext>();
312     taiheContext->rImageSource = imageSourceImpl->nativeImgSrc;
313     taiheContext->packType = TYPE_IMAGE_SOURCE;
314     taiheContext->rImagePacker = nativeImagePacker_;
315     taiheContext->packOption = ParsePackOptions(options);
316     taiheContext->fd = fd;
317     if (!CheckPackToFileContext(taiheContext)) {
318         return;
319     }
320 
321     ImageTaiheUtils::HicheckerReport();
322 
323     if (!PackToFileExec(taiheContext)) {
324         IMAGE_LOGE("PackToFileExec Failed");
325     }
326 }
327 
PackPixelMapToFileSync(weak::PixelMap source,int32_t fd,PackingOption const & options)328 void ImagePackerImpl::PackPixelMapToFileSync(weak::PixelMap source, int32_t fd, PackingOption const& options)
329 {
330     OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackPixelMapToFile");
331 
332     PixelMapImpl* pixelMapImpl = reinterpret_cast<PixelMapImpl*>(source->GetImplPtr());
333     if (pixelMapImpl == nullptr) {
334         return;
335     }
336     std::unique_ptr<ImagePackerTaiheContext> taiheContext = std::make_unique<ImagePackerTaiheContext>();
337     taiheContext->rPixelMap = pixelMapImpl->GetNativePtr();
338     taiheContext->packType = TYPE_PIXEL_MAP;
339     taiheContext->rImagePacker = nativeImagePacker_;
340     taiheContext->packOption = ParsePackOptions(options);
341     taiheContext->fd = fd;
342     if (!CheckPackToFileContext(taiheContext)) {
343         return;
344     }
345 
346     ImageTaiheUtils::HicheckerReport();
347 
348     if (!PackToFileExec(taiheContext)) {
349         IMAGE_LOGE("PackToFileExec Failed");
350     }
351 }
352 
PackPictureToFileSync(weak::Picture picture,int32_t fd,PackingOption const & options)353 void ImagePackerImpl::PackPictureToFileSync(weak::Picture picture, int32_t fd, PackingOption const& options)
354 {
355 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
356     OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackPictureToFile");
357 
358     PictureImpl* pictureImpl = reinterpret_cast<PictureImpl*>(picture->GetImplPtr());
359     if (pictureImpl == nullptr) {
360         return;
361     }
362     std::unique_ptr<ImagePackerTaiheContext> taiheContext = std::make_unique<ImagePackerTaiheContext>();
363     taiheContext->rPicture = pictureImpl->GetNativePtr();
364     taiheContext->packType = TYPE_PIXEL_MAP;
365     taiheContext->rImagePacker = nativeImagePacker_;
366     taiheContext->packOption = ParsePackOptions(options);
367     taiheContext->fd = fd;
368     if (!CheckPackToFileContext(taiheContext)) {
369         return;
370     }
371 
372     ImageTaiheUtils::HicheckerReport();
373 
374     if (!PackToFileExec(taiheContext)) {
375         IMAGE_LOGE("PackToFileExec Failed");
376     }
377 #endif
378 }
379 
ThrowPackingError(std::unique_ptr<ImagePackerTaiheContext> & ctx,int32_t errorCode,const std::string msg)380 static void ThrowPackingError(std::unique_ptr<ImagePackerTaiheContext> &ctx, int32_t errorCode, const std::string msg)
381 {
382     if (ctx == nullptr) {
383         ImageTaiheUtils::ThrowExceptionError("ImagePacker taihe context is nullptr");
384         return;
385     }
386     if (ctx->needReturnErrorCode) {
387         ImageTaiheUtils::ThrowExceptionError(errorCode, msg);
388     } else {
389         ImageTaiheUtils::ThrowExceptionError(msg);
390     }
391 }
392 
FinalizePacking(std::unique_ptr<ImagePackerTaiheContext> & context,int32_t innerEncodeErrorCode)393 static bool FinalizePacking(std::unique_ptr<ImagePackerTaiheContext> &context, int32_t innerEncodeErrorCode)
394 {
395     int64_t packedSize = 0;
396     auto packRes = context->rImagePacker->FinalizePacking(packedSize);
397     IMAGE_LOGD("packedSize=%{public}" PRId64, packedSize);
398     if (packRes == OHOS::Media::SUCCESS) {
399         context->packedSize = packedSize;
400         return true;
401     } else if (packedSize == context->resultBufferSize) {
402         if (context->packType == TYPE_PICTURE) {
403             ThrowPackingError(context, IMAGE_ENCODE_FAILED, "output buffer is not enough");
404         } else {
405             ThrowPackingError(context, OHOS::Media::ERR_IMAGE_TOO_LARGE, "output buffer is not enough");
406         }
407         IMAGE_LOGE("output buffer is not enough.");
408         return false;
409     } else {
410         IMAGE_LOGE("Packing failed, packedSize outside size.");
411         ThrowPackingError(context, packRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ?
412             OHOS::Media::COMMON_ERR_INVALID_PARAMETER : innerEncodeErrorCode, "Packing failed");
413         return false;
414     }
415 }
416 
PackingExec(std::unique_ptr<ImagePackerTaiheContext> & context)417 static bool PackingExec(std::unique_ptr<ImagePackerTaiheContext> &context)
418 {
419     IMAGE_LOGD("ImagePacker BufferSize %{public}" PRId64, context->resultBufferSize);
420     context->resultBuffer = std::make_unique<uint8_t[]>(
421         (context->resultBufferSize <= 0) ? GetDefaultBufferSize(context) : context->resultBufferSize);
422     int32_t innerEncodeErrorCode = static_cast<int32_t>(
423         context->packType == TYPE_PICTURE ? IMAGE_ENCODE_FAILED : OHOS::Media::ERR_IMAGE_ENCODE_FAILED);
424     if (context->resultBuffer == nullptr) {
425         ThrowPackingError(context, innerEncodeErrorCode, "ImagePacker buffer alloc error");
426         return false;
427     }
428     auto startRes = context->rImagePacker->StartPacking(context->resultBuffer.get(),
429     context->resultBufferSize, context->packOption);
430     if (startRes != OHOS::Media::SUCCESS) {
431         ThrowPackingError(context, startRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ?
432             OHOS::Media::COMMON_ERR_INVALID_PARAMETER : innerEncodeErrorCode, "Packing start packing failed");
433         return false;
434     }
435     if (context->packType == TYPE_IMAGE_SOURCE) {
436         IMAGE_LOGI("ImagePacker set image source");
437         if (context->rImageSource == nullptr) {
438             ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "ImageSource is nullptr");
439             return false;
440         }
441         context->rImagePacker->AddImage(*(context->rImageSource));
442     } else if (context->packType == TYPE_PIXEL_MAP) {
443         IMAGE_LOGD("ImagePacker set pixelmap");
444         if (context->rPixelMap == nullptr) {
445             ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Pixelmap is nullptr");
446             return false;
447         }
448         context->rImagePacker->AddImage(*(context->rPixelMap));
449 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
450     } else if (context->packType == TYPE_PICTURE) {
451         if (!SetPicture(context)) {
452             return false;
453         }
454 #endif
455     } else if (context->packType == TYPE_ARRAY) {
456         if (!SetArrayPixel(context)) {
457             return false;
458         }
459     }
460     return FinalizePacking(context, innerEncodeErrorCode);
461 }
462 
PackingComplete(std::unique_ptr<ImagePackerTaiheContext> & context)463 static array<uint8_t> PackingComplete(std::unique_ptr<ImagePackerTaiheContext> &context)
464 {
465     if (context == nullptr) {
466         ImageTaiheUtils::ThrowExceptionError("PackingComplete context is nullptr!");
467         return array<uint8_t>(0);
468     }
469 
470     array<uint8_t> arrayBuffer = ImageTaiheUtils::CreateTaiheArrayBuffer(context->resultBuffer.get(),
471         context->packedSize);
472     if (arrayBuffer.empty()) {
473         ImageTaiheUtils::ThrowExceptionError("CreateTaiheArrayBuffer failed!");
474     }
475 
476     context->resultBuffer = nullptr;
477     context->resultBufferSize = 0;
478     return arrayBuffer;
479 }
480 
CheckPackingContext(std::unique_ptr<ImagePackerTaiheContext> & context)481 static bool CheckPackingContext(std::unique_ptr<ImagePackerTaiheContext> &context)
482 {
483     if (context->rImagePacker == nullptr) {
484         ThrowPackingError(context, OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "native ImagePacker is nullptr");
485         return false;
486     }
487     if (context->packType == TYPE_IMAGE_SOURCE) {
488         if (context->rImageSource == nullptr) {
489             ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "ImageSource is nullptr");
490             return false;
491         }
492     } else if (context->packType == TYPE_PIXEL_MAP) {
493         if (context->rPixelMap == nullptr) {
494             ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMap is nullptr");
495             return false;
496         }
497 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
498     } else if (context->packType == TYPE_PICTURE) {
499         if (context->rPicture == nullptr) {
500             ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Picture is nullptr");
501             return false;
502         }
503 #endif
504     } else if (context->packType == TYPE_ARRAY) {
505         if (context->rPixelMaps == nullptr) {
506             ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMaps is nullptr");
507             return false;
508         }
509     }
510     return true;
511 }
512 
Packing(std::unique_ptr<ImagePackerTaiheContext> & taiheContext)513 static array<uint8_t> Packing(std::unique_ptr<ImagePackerTaiheContext>& taiheContext)
514 {
515     ImageTaiheUtils::HicheckerReport();
516 
517     if (!CheckPackingContext(taiheContext)) {
518         return array<uint8_t>(0);
519     }
520 
521     if (!PackingExec(taiheContext)) {
522         IMAGE_LOGE("PackingExec Failed");
523         return array<uint8_t>(0);
524     }
525     return PackingComplete(taiheContext);
526 }
527 
PackingPixelMapSync(weak::PixelMap source,PackingOption const & option)528 array<uint8_t> ImagePackerImpl::PackingPixelMapSync(weak::PixelMap source, PackingOption const& option)
529 {
530     OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackingPixelMapSync");
531     IMAGE_LOGI("PackingPixelMapSync IN");
532 
533     std::unique_ptr<ImagePackerTaiheContext> taiheContext = std::make_unique<ImagePackerTaiheContext>();
534     PixelMapImpl* pixelMapImpl = reinterpret_cast<PixelMapImpl*>(source->GetImplPtr());
535     if (pixelMapImpl == nullptr) {
536         ImageTaiheUtils::ThrowExceptionError("fail to unwrap pixelMapImpl.");
537         return array<uint8_t>(0);
538     }
539     taiheContext->needReturnErrorCode = false;
540 
541     taiheContext->rImagePacker = nativeImagePacker_;
542     taiheContext->packType = TYPE_PIXEL_MAP;
543     taiheContext->rPixelMap = pixelMapImpl->GetNativePtr();
544     taiheContext->packOption = ParsePackOptions(option);
545     taiheContext->resultBufferSize = ParseBufferSize(taiheContext, option);
546 
547     return Packing(taiheContext);
548 }
549 
PackingPictureSync(weak::Picture picture,PackingOption const & options)550 array<uint8_t> ImagePackerImpl::PackingPictureSync(weak::Picture picture, PackingOption const& options)
551 {
552 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
553     OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackingPictureSync");
554     IMAGE_LOGI("PackingPictureSync IN");
555 
556     std::unique_ptr<ImagePackerTaiheContext> taiheContext = std::make_unique<ImagePackerTaiheContext>();
557     PictureImpl* pictureImpl = reinterpret_cast<PictureImpl*>(picture->GetImplPtr());
558     if (pictureImpl == nullptr) {
559         ImageTaiheUtils::ThrowExceptionError("Unwarp pictureImpl failed.");
560         return array<uint8_t>(0);
561     }
562     taiheContext->needReturnErrorCode = true;
563 
564     taiheContext->rImagePacker = nativeImagePacker_;
565     taiheContext->packType = TYPE_PICTURE;
566     taiheContext->rPicture = pictureImpl->GetNativePtr();
567     taiheContext->packOption = ParsePackOptions(options);
568     taiheContext->resultBufferSize = ParseBufferSize(taiheContext, options);
569 
570     return Packing(taiheContext);
571 #else
572     ImageTaiheUtils::ThrowExceptionError("Invalid type!");
573 #endif
574 }
575 
ReleaseSync()576 void ImagePackerImpl::ReleaseSync()
577 {
578     if (!isRelease) {
579         nativeImagePacker_ = nullptr;
580         isRelease = true;
581     }
582 }
583 
GetSupportedFormats()584 array<string> ImagePackerImpl::GetSupportedFormats()
585 {
586     std::set<std::string> formats;
587     nativeImagePacker_->GetSupportedFormats(formats);
588     std::vector<std::string> vec(formats.begin(), formats.end());
589     return ImageTaiheUtils::ToTaiheArrayString(vec);
590 }
591 
CreateImagePacker()592 ImagePacker CreateImagePacker()
593 {
594     OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::CreateImagePacker");
595     std::shared_ptr<OHOS::Media::ImagePacker> imagePacker = std::make_shared<OHOS::Media::ImagePacker>();
596     return make_holder<ImagePackerImpl, ImagePacker>(imagePacker);
597 }
598 } // namespace ANI::Image
599 
600 TH_EXPORT_CPP_API_CreateImagePacker(CreateImagePacker);