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);