• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "ext_encoder.h"
17 #include <algorithm>
18 #include <map>
19 
20 #include "include/core/SkImageEncoder.h"
21 #include "src/images/SkImageEncoderFns.h"
22 #include "include/core/SkBitmap.h"
23 #include "pixel_yuv_utils.h"
24 #ifdef IMAGE_COLORSPACE_FLAG
25 #include "color_space.h"
26 #endif
27 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
28 #include "astc_codec.h"
29 #endif
30 
31 #include "ext_pixel_convert.h"
32 #include "ext_wstream.h"
33 #include "image_data_statistics.h"
34 #include "image_dfx.h"
35 #include "image_func_timer.h"
36 #include "image_fwk_ext_manager.h"
37 #include "image_log.h"
38 #include "image_system_properties.h"
39 #include "image_type_converter.h"
40 #include "image_utils.h"
41 #include "jpeg_mpf_parser.h"
42 #include "media_errors.h"
43 #include "metadata_accessor.h"
44 #include "metadata_accessor_factory.h"
45 #include "pixel_map_utils.h"
46 #include "pixel_convert_adapter.h"
47 #include "string_ex.h"
48 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
49 #include "surface_buffer.h"
50 #include "v1_0/buffer_handle_meta_key_type.h"
51 #include "v1_0/cm_color_space.h"
52 #include "v1_0/hdr_static_metadata.h"
53 #include "vpe_utils.h"
54 #include "hdr_helper.h"
55 #endif
56 #include "color_utils.h"
57 #include "tiff_parser.h"
58 #include "image_mime_type.h"
59 #include "securec.h"
60 #include "file_packer_stream.h"
61 #include "memory_manager.h"
62 #ifdef HEIF_HW_ENCODE_ENABLE
63 #include "v2_0/icodec_image.h"
64 #include "iremote_object.h"
65 #include "iproxy_broker.h"
66 #endif
67 
68 #undef LOG_DOMAIN
69 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_PLUGIN
70 
71 #undef LOG_TAG
72 #define LOG_TAG "ExtEncoder"
73 
74 namespace OHOS {
75 namespace ImagePlugin {
76 using namespace Media;
77 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
78 using namespace HDI::Display::Graphic::Common::V1_0;
79 const std::map<PixelFormat, GraphicPixelFormat> SURFACE_FORMAT_MAP = {
80     { PixelFormat::RGBA_8888, GRAPHIC_PIXEL_FMT_RGBA_8888 },
81     { PixelFormat::NV21, GRAPHIC_PIXEL_FMT_YCRCB_420_SP },
82     { PixelFormat::NV12, GRAPHIC_PIXEL_FMT_YCBCR_420_SP },
83 };
84 #endif
85 
86 namespace {
87     constexpr static uint32_t PRIMARY_IMAGE_ITEM_ID = 1;
88     constexpr static uint32_t GAINMAP_IMAGE_ITEM_ID = 2;
89     constexpr static uint32_t TMAP_IMAGE_ITEM_ID = 3;
90     constexpr static uint32_t EXIF_META_ITEM_ID = 4;
91     constexpr static uint32_t DEPTH_MAP_ITEM_ID = 5;
92     constexpr static uint32_t UNREFOCUS_MAP_ITEM_ID = 6;
93     constexpr static uint32_t LINEAR_MAP_ITEM_ID = 7;
94     constexpr static uint32_t FRAGMENT_MAP_ITEM_ID = 8;
95     const static std::string COMPRESS_TYPE_TMAP = "tmap";
96     const static std::string COMPRESS_TYPE_HEVC = "hevc";
97     const static std::string COMPRESS_TYPE_NONE = "none";
98     const static std::string DEFAULT_ASHMEM_TAG = "Heif Encoder Default";
99     const static std::string ICC_ASHMEM_TAG = "Heif Encoder Property";
100     const static std::string IT35_ASHMEM_TAG = "Heif Encoder IT35";
101     const static std::string OUTPUT_ASHMEM_TAG = "Heif Encoder Output";
102     const static std::string IMAGE_DATA_TAG = "Heif Encoder Image";
103     const static std::string HDR_GAINMAP_TAG = "Heif Encoder Gainmap";
104     const static std::string EXIF_ASHMEM_TAG = "Heif Encoder Exif";
105     const static std::string GAINMAP_IMAGE_ITEM_NAME = "Gain map Image";
106     const static std::string DEPTH_MAP_ITEM_NAME =  "Depth Map Image";
107     const static std::string UNREFOCUS_MAP_ITEM_NAME = "Unrefocus Map Image";
108     const static std::string LINEAR_MAP_ITEM_NAME = "Linear Map Image";
109     const static std::string FRAGMENT_MAP_ITEM_NAME = "Fragment Map Image";
110     const static size_t DEFAULT_OUTPUT_SIZE = 35 * 1024 * 1024; // 35M
111     const static uint16_t STATIC_METADATA_COLOR_SCALE = 50000;
112     const static uint16_t STATIC_METADATA_LUM_SCALE = 10000;
113     const static uint8_t INDEX_ZERO = 0;
114     const static uint8_t INDEX_ONE = 1;
115     const static uint8_t INDEX_TWO = 2;
116     constexpr uint32_t DEFAULT_DENOMINATOR = 1000000;
117     constexpr uint8_t GAINMAP_CHANNEL_MULTI = 3;
118     constexpr uint8_t GAINMAP_CHANNEL_SINGLE = 1;
119     constexpr uint8_t EXIF_PRE_SIZE = 6;
120     constexpr uint32_t JPEG_MARKER_TAG_SIZE = 2;
121     constexpr uint32_t DEPTH_MAP_BYTES = sizeof(float); // float16
122     constexpr uint32_t LINEAR_MAP_BYTES = sizeof(short) * 3 / 2; // 16bit yuv420
123     constexpr uint32_t PLACE_HOLDER_LENGTH = 1;
124     constexpr uint32_t LOW_QUALITY_BOUNDARY = 85;
125 
126     // exif/0/0
127     constexpr uint8_t EXIF_PRE_TAG[EXIF_PRE_SIZE] = {
128         0x45, 0x78, 0x69, 0x66, 0x00, 0x00
129     };
130 }
131 
132 struct HeifEncodeItemInfo {
133     uint32_t itemId = 0;
134     std::string itemName = "";
135     std::string itemType = "";
136 };
137 
138 static const std::map<std::string, SkEncodedImageFormat> FORMAT_NAME = {
139     {IMAGE_BMP_FORMAT, SkEncodedImageFormat::kBMP},
140     {IMAGE_GIF_FORMAT, SkEncodedImageFormat::kGIF},
141     {IMAGE_ICO_FORMAT, SkEncodedImageFormat::kICO},
142     {IMAGE_JPEG_FORMAT, SkEncodedImageFormat::kJPEG},
143     {IMAGE_PNG_FORMAT, SkEncodedImageFormat::kPNG},
144     {IMAGE_WBMP_FORMAT, SkEncodedImageFormat::kWBMP},
145     {IMAGE_WEBP_FORMAT, SkEncodedImageFormat::kWEBP},
146     {IMAGE_HEIF_FORMAT, SkEncodedImageFormat::kHEIF},
147     {IMAGE_HEIC_FORMAT, SkEncodedImageFormat::kHEIF},
148 };
149 
150 static const std::map<AuxiliaryPictureType, std::string> DEFAULT_AUXILIARY_TAG_MAP = {
151     {AuxiliaryPictureType::GAINMAP, AUXILIARY_TAG_GAINMAP},
152     {AuxiliaryPictureType::DEPTH_MAP, AUXILIARY_TAG_DEPTH_MAP_BACK},
153     {AuxiliaryPictureType::UNREFOCUS_MAP, AUXILIARY_TAG_UNREFOCUS_MAP},
154     {AuxiliaryPictureType::LINEAR_MAP, AUXILIARY_TAG_LINEAR_MAP},
155     {AuxiliaryPictureType::FRAGMENT_MAP, AUXILIARY_TAG_FRAGMENT_MAP},
156 };
157 
158 static const uint8_t NUM_3 = 3;
159 static const uint8_t NUM_4 = 4;
160 static const uint8_t RGBA_BIT_DEPTH = 4;
161 
162 static constexpr int32_t MAX_IMAGE_SIZE = 8196;
163 static constexpr int32_t MIN_IMAGE_SIZE = 128;
164 static constexpr int32_t MIN_RGBA_IMAGE_SIZE = 1024;
165 
166 #ifdef HEIF_HW_ENCODE_ENABLE
167 using namespace OHOS::HDI::Codec::Image::V2_0;
168 static std::mutex g_codecMtx;
169 static sptr<ICodecImage> g_codecMgr;
170 class CodecHeifDeathRecipient : public IRemoteObject::DeathRecipient {
171 public:
OnRemoteDied(const wptr<OHOS::IRemoteObject> & object)172     void OnRemoteDied(const wptr<OHOS::IRemoteObject>& object) override
173     {
174         IMAGE_LOGW("codec_image_service died");
175         std::lock_guard<std::mutex> lk(g_codecMtx);
176         g_codecMgr = nullptr;
177     }
178 };
179 
GetCodecManager()180 static sptr<ICodecImage> GetCodecManager()
181 {
182     std::lock_guard<std::mutex> lk(g_codecMtx);
183     if (g_codecMgr) {
184         return g_codecMgr;
185     }
186     IMAGE_LOGI("need to get ICodecImage");
187     g_codecMgr = ICodecImage::Get();
188     bool cond = g_codecMgr == nullptr;
189     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "ICodecImage get failed");
190     bool isDeathRecipientAdded = false;
191     const sptr<OHOS::IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ICodecImage>(g_codecMgr);
192     if (remote) {
193         sptr<CodecHeifDeathRecipient> deathCallBack(new CodecHeifDeathRecipient());
194         isDeathRecipientAdded = remote->AddDeathRecipient(deathCallBack);
195     }
196     if (!isDeathRecipientAdded) {
197         IMAGE_LOGI("failed to add deathRecipient for ICodecImage!");
198     }
199     return g_codecMgr;
200 }
201 #endif
202 
ExtEncoder()203 ExtEncoder::ExtEncoder()
204 {
205 }
206 
~ExtEncoder()207 ExtEncoder::~ExtEncoder()
208 {
209     if (releasePixelMap_ && pixelmap_ != nullptr) {
210         delete pixelmap_;
211         pixelmap_ = nullptr;
212     }
213     if (releasePicture_ && picture_ != nullptr) {
214         delete picture_;
215         picture_ = nullptr;
216     }
217 }
218 
StartEncode(OutputDataStream & outputStream,PlEncodeOptions & option)219 uint32_t ExtEncoder::StartEncode(OutputDataStream &outputStream, PlEncodeOptions &option)
220 {
221     output_ = &outputStream;
222     opts_ = option;
223     return SUCCESS;
224 }
225 
AddImage(PixelMap & pixelMap)226 uint32_t ExtEncoder::AddImage(PixelMap &pixelMap)
227 {
228     pixelmap_ = &pixelMap;
229     return SUCCESS;
230 }
231 
AddPicture(Media::Picture & picture)232 uint32_t ExtEncoder::AddPicture(Media::Picture &picture)
233 {
234     picture_ = &picture;
235     return SUCCESS;
236 }
237 
238 struct TmpBufferHolder {
239     std::unique_ptr<uint8_t[]> buf = nullptr;
240 };
241 
242 struct ImageData {
243     uint8_t *dst;
244     uint8_t *pixels;
245     ImageInfo info;
246 };
247 
ToSkColorSpace(PixelMap * pixelmap)248 static sk_sp<SkColorSpace> ToSkColorSpace(PixelMap *pixelmap)
249 {
250 #ifdef IMAGE_COLORSPACE_FLAG
251     bool cond = pixelmap->InnerGetGrColorSpacePtr() == nullptr;
252     CHECK_ERROR_RETURN_RET(cond, nullptr);
253 
254     cond = pixelmap->InnerGetGrColorSpace().GetColorSpaceName() == ColorManager::ColorSpaceName::NONE;
255     CHECK_ERROR_RETURN_RET(cond, SkColorSpace::MakeSRGB());
256     return pixelmap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
257 #else
258     return nullptr;
259 #endif
260 }
261 
ToSkInfo(Media::PixelMap * pixelMap)262 static SkImageInfo ToSkInfo(Media::PixelMap *pixelMap)
263 {
264     ImageInfo info;
265     pixelMap->GetImageInfo(info);
266     SkColorType colorType = ImageTypeConverter::ToSkColorType(info.pixelFormat);
267     SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(info.alphaType);
268     sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
269 #ifdef IMAGE_COLORSPACE_FLAG
270     if (pixelMap->InnerGetGrColorSpacePtr() != nullptr &&
271         pixelMap->InnerGetGrColorSpace().GetColorSpaceName() != ColorManager::ColorSpaceName::NONE) {
272         colorSpace = pixelMap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
273     }
274 #endif
275     return SkImageInfo::Make(info.size.width, info.size.height, colorType, alphaType, colorSpace);
276 }
277 
RGBToRGBx(PixelMap * pixelMap,SkImageInfo & skInfo,TmpBufferHolder & holder)278 static uint32_t RGBToRGBx(PixelMap *pixelMap, SkImageInfo &skInfo, TmpBufferHolder &holder)
279 {
280     holder.buf = std::make_unique<uint8_t[]>(skInfo.computeMinByteSize());
281     ExtPixels src = {
282         static_cast<uint8_t*>(pixelMap->GetWritablePixels()),
283         pixelMap->GetCapacity(), pixelMap->GetWidth()*pixelMap->GetHeight(),
284     };
285     ExtPixels dst = {
286         holder.buf.get(), skInfo.computeMinByteSize(), skInfo.width()*skInfo.height(),
287     };
288     return ExtPixelConvert::RGBToRGBx(src, dst);
289 }
290 
IsYuvImage(PixelFormat format)291 static bool IsYuvImage(PixelFormat format)
292 {
293     return format == PixelFormat::NV21 || format == PixelFormat::NV12;
294 }
295 
YuvToRgbaSkInfo(ImageInfo info,SkImageInfo & skInfo,uint8_t * dstData,Media::PixelMap * pixelMap)296 static uint32_t YuvToRgbaSkInfo(ImageInfo info, SkImageInfo &skInfo, uint8_t * dstData, Media::PixelMap *pixelMap)
297 {
298     uint8_t *srcData = static_cast<uint8_t*>(pixelMap->GetWritablePixels());
299     YUVDataInfo yuvInfo;
300     pixelMap->GetImageYUVInfo(yuvInfo);
301     YuvImageInfo srcInfo = {PixelYuvUtils::ConvertFormat(info.pixelFormat),
302         info.size.width, info.size.height, info.pixelFormat, yuvInfo};
303     YuvImageInfo dstInfo = {PixelYuvUtils::ConvertFormat(PixelFormat::RGBA_8888), info.size.width, info.size.height};
304     bool cond = !PixelConvertAdapter::YUV420ToRGB888(srcData, srcInfo, dstData, dstInfo);
305     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "YuvToSkInfo Support YUV format RGB convert failed ");
306     auto alpha = pixelMap->GetAlphaType();
307     if (alpha == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN)
308         alpha = AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
309     SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(alpha);
310     auto cs = ToSkColorSpace(pixelMap);
311     skInfo = SkImageInfo::Make(info.size.width, info.size.height, SkColorType::kRGBA_8888_SkColorType, alphaType, cs);
312     IMAGE_LOGD(" YuvToSkInfo: width:%{public}d, height:%{public}d, alpha:%{public}d \n ",
313         info.size.width, info.size.height, (int32_t)alphaType);
314     return SUCCESS;
315 }
316 
pixelToSkInfo(ImageData & image,SkImageInfo & skInfo,Media::PixelMap * pixelMap,TmpBufferHolder & holder,SkEncodedImageFormat format)317 static uint32_t pixelToSkInfo(ImageData &image, SkImageInfo &skInfo, Media::PixelMap *pixelMap,
318     TmpBufferHolder &holder, SkEncodedImageFormat format)
319 {
320     skInfo = ToSkInfo(pixelMap);
321     image.pixels = static_cast<uint8_t*>(pixelMap->GetWritablePixels());
322     if (format == SkEncodedImageFormat::kJPEG &&
323         skInfo.colorType() == SkColorType::kRGB_888x_SkColorType &&
324         pixelMap->GetCapacity() < skInfo.computeMinByteSize()) {
325         uint32_t res = RGBToRGBx(pixelMap, skInfo, holder);
326         bool cond = res != SUCCESS;
327         CHECK_ERROR_RETURN_RET_LOG(cond, res, "ExtEncoder::BuildSkBitmap RGB convert failed %{public}d", res);
328         image.pixels = holder.buf.get();
329         skInfo = skInfo.makeColorType(SkColorType::kRGBA_8888_SkColorType);
330     }
331     return SUCCESS;
332 }
333 
IsAstc(const std::string & format)334 bool IsAstc(const std::string &format)
335 {
336     return format.find("image/astc") == 0;
337 }
338 
CreateAndWriteBlob(MetadataWStream & tStream,PixelMap * pixelmap,SkWStream & outStream,ImageInfo & imageInfo,PlEncodeOptions & opts)339 static uint32_t CreateAndWriteBlob(MetadataWStream &tStream, PixelMap *pixelmap, SkWStream& outStream,
340     ImageInfo &imageInfo, PlEncodeOptions &opts)
341 {
342     ImageFuncTimer imageFuncTimer("insert exif data (%d, %d)", imageInfo.size.width, imageInfo.size.height);
343     auto metadataAccessor =
344         MetadataAccessorFactory::Create(tStream.GetAddr(), tStream.bytesWritten(), BufferMetadataStream::Dynamic);
345     if (metadataAccessor != nullptr) {
346         auto metadataPtr = pixelmap->GetExifMetadata();
347         metadataAccessor->Set(metadataPtr);
348         if (metadataAccessor->Write() == SUCCESS) {
349             if (metadataAccessor->WriteToOutput(outStream)) {
350                 return SUCCESS;
351             }
352         }
353     }
354     if (!outStream.write(tStream.GetAddr(), tStream.bytesWritten())) {
355         ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts.format, "Failed to encode image");
356         return ERR_IMAGE_ENCODE_FAILED;
357     }
358     return SUCCESS;
359 }
360 
PixelmapEncode(ExtWStream & wStream)361 uint32_t ExtEncoder::PixelmapEncode(ExtWStream& wStream)
362 {
363     uint32_t error;
364 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
365     IMAGE_LOGD("pixelmapEncode EncodeImageByPixelMap");
366     error = EncodeImageByPixelMap(pixelmap_, opts_.needsPackProperties, wStream);
367 #else
368     switch (opts_.desiredDynamicRange) {
369         case EncodeDynamicRange::AUTO:
370             if (pixelmap_->IsHdr() &&
371                 (encodeFormat_ == SkEncodedImageFormat::kJPEG || encodeFormat_ == SkEncodedImageFormat::kHEIF)) {
372                 error = EncodeDualVivid(wStream);
373             } else {
374                 error = EncodeSdrImage(wStream);
375             }
376             break;
377         case EncodeDynamicRange::SDR:
378             error = EncodeSdrImage(wStream);
379             break;
380         case EncodeDynamicRange::HDR_VIVID_DUAL:
381             error = EncodeDualVivid(wStream);
382             break;
383         case EncodeDynamicRange::HDR_VIVID_SINGLE:
384             error = EncodeSingleVivid(wStream);
385             break;
386         default:
387             error = ERR_IMAGE_ENCODE_FAILED;
388             break;
389     }
390 #endif
391     RecycleResources();
392     return error;
393 }
394 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
IsSuperFastEncode(const std::string & format)395 bool IsSuperFastEncode(const std::string &format)
396 {
397     return SUT_FORMAT_MAP.find(format) != SUT_FORMAT_MAP.end() ||
398         ASTC_FORMAT_MAP.find(format) != ASTC_FORMAT_MAP.end();
399 }
400 #endif
401 
402 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
CheckPictureHasArgb(Picture * picture)403 static bool CheckPictureHasArgb(Picture *picture)
404 {
405     bool cond = picture == nullptr || picture->GetMainPixel() == nullptr;
406     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s picture is nullptr or mainPixelMap is nullptr", __func__);
407     if (picture->GetMainPixel()->GetPixelFormat() == PixelFormat::ARGB_8888) {
408         IMAGE_LOGI("%{public}s picture has ARGB format. mainPixelMap is ARGB!", __func__);
409         return true;
410     }
411     IMAGE_LOGD("%{public}s picture does not have ARGB format.", __func__);
412     return false;
413 }
414 
ConvertToRgbaPicture(Picture * picture)415 static std::unique_ptr<Picture> ConvertToRgbaPicture(Picture *picture)
416 {
417     bool cond = picture == nullptr || picture->GetMainPixel() == nullptr;
418     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
419         "%{public}s picture or mainPixelMap is nullptr!", __func__);
420     cond = !CheckPictureHasArgb(picture);
421     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "%{public}s no need to convert!", __func__);
422 
423     std::shared_ptr<PixelMap> mainPixelMap = picture->GetMainPixel();
424     std::unique_ptr<Picture> newPicture = Picture::Create(mainPixelMap);
425     cond = newPicture == nullptr;
426     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
427         "%{public}s newPicture create failed! Stop ConvertToRgbaPicture.", __func__);
428     int32_t errorCode;
429     if (mainPixelMap->GetPixelFormat() == PixelFormat::ARGB_8888) {
430         std::shared_ptr<PixelMap> newPixelMap = mainPixelMap->Clone(errorCode);
431         cond = errorCode != SUCCESS || newPixelMap == nullptr ||
432             ConvertArgbAndRgba(newPixelMap.get(), PixelFormat::RGBA_8888) != SUCCESS;
433         CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
434             "%{public}s mainPixelMap Convert failed! Stop ConvertToRgbaPicture.", __func__);
435         newPicture->SetMainPixel(newPixelMap);
436     }
437 
438     sptr<SurfaceBuffer> maintenanceData = picture->GetMaintenanceData();
439     if (maintenanceData != nullptr) {
440         cond = !newPicture->SetMaintenanceData(maintenanceData);
441         CHECK_ERROR_PRINT_LOG(cond, "%{public}s SetMaintenanceData for newPicture failed!", __func__);
442     }
443     std::shared_ptr<ExifMetadata> exifMetadata = picture->GetExifMetadata();
444     if (exifMetadata != nullptr) {
445         cond = newPicture->SetExifMetadata(exifMetadata) != SUCCESS;
446         CHECK_ERROR_PRINT_LOG(cond, "%{public}s SetExifMetadata for newPicture failed!", __func__);
447     }
448     return newPicture;
449 }
450 
CheckArgbEncode()451 uint32_t ExtEncoder::CheckArgbEncode()
452 {
453     if (pixelmap_ != nullptr && pixelmap_->GetPixelFormat() == PixelFormat::ARGB_8888) {
454         int32_t errorCode = ERROR;
455         std::unique_ptr<PixelMap> newPixelMap = pixelmap_->Clone(errorCode);
456         if (errorCode != SUCCESS || ConvertArgbAndRgba(newPixelMap.get(), PixelFormat::RGBA_8888) != SUCCESS) {
457             IMAGE_LOGE("%{public}s Pixelmap Convert ARGB to RGBA failed!", __func__);
458             return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
459         }
460         pixelmap_ = newPixelMap.release();
461         releasePixelMap_ = true;
462         IMAGE_LOGI("%{public}s PixelMap Convert ARGB to RGBA success!", __func__);
463     }
464     if (picture_ != nullptr && CheckPictureHasArgb(picture_)) {
465         std::unique_ptr<Picture> newPicture = ConvertToRgbaPicture(picture_);
466         if (newPicture == nullptr) {
467             IMAGE_LOGE("%{public}s picture's mainPixelMap Convert ARGB to RGBA failed!", __func__);
468             return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
469         }
470         picture_ = newPicture.release();
471         releasePicture_ = true;
472         IMAGE_LOGI("%{public}s picture's mainPixelMap Convert ARGB to RGBA success!", __func__);
473     }
474     return SUCCESS;
475 }
476 #endif
477 
FinalizeEncode()478 uint32_t ExtEncoder::FinalizeEncode()
479 {
480     if ((picture_ == nullptr && pixelmap_ == nullptr) || output_ == nullptr) {
481         return ERR_IMAGE_INVALID_PARAMETER;
482     }
483 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
484     uint32_t convertRes = CheckArgbEncode();
485     if (convertRes != SUCCESS) {
486         return convertRes;
487     }
488 #endif
489     ImageDataStatistics imageDataStatistics("[ExtEncoder]FinalizeEncode imageFormat = %s, quality = %d",
490         opts_.format.c_str(), opts_.quality);
491 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
492     if (IsAstc(opts_.format) || IsSuperFastEncode(opts_.format)) {
493         AstcCodec astcEncoder;
494         astcEncoder.SetAstcEncode(output_, opts_, pixelmap_);
495         return astcEncoder.ASTCEncode();
496     }
497 #endif
498     auto iter = FORMAT_NAME.find(LowerStr(opts_.format));
499     if (iter == FORMAT_NAME.end()) {
500         IMAGE_LOGE("ExtEncoder::FinalizeEncode unsupported format %{public}s", opts_.format.c_str());
501         ReportEncodeFault(0, 0, opts_.format, "Unsupported format:" + opts_.format);
502         return ERR_IMAGE_INVALID_PARAMETER;
503     }
504 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
505     if (picture_ != nullptr) {
506         encodeFormat_ = iter->second;
507         if ((encodeFormat_ == SkEncodedImageFormat::kHEIF) &&
508             picture_->GetMainPixel()->GetAllocatorType() == Media::AllocatorType::SHARE_MEM_ALLOC) {
509             pixelmap_ = picture_->GetMainPixel().get();
510             return EncodeHeifByPixelmap(picture_->GetMainPixel().get(), opts_);
511         }
512         return EncodePicture();
513     }
514 #endif
515     ImageInfo imageInfo;
516     pixelmap_->GetImageInfo(imageInfo);
517     imageDataStatistics.AddTitle(", width = %d, height =%d", imageInfo.size.width, imageInfo.size.height);
518     encodeFormat_ = iter->second;
519     ExtWStream wStream(output_);
520     return PixelmapEncode(wStream);
521 }
522 
IsHardwareEncodeSupported(const PlEncodeOptions & opts,Media::PixelMap * pixelMap)523 bool ExtEncoder::IsHardwareEncodeSupported(const PlEncodeOptions &opts, Media::PixelMap* pixelMap)
524 {
525     if (pixelMap == nullptr) {
526         IMAGE_LOGE("pixelMap is nullptr");
527         return false;
528     }
529     if (opts.quality < LOW_QUALITY_BOUNDARY) {
530         IMAGE_LOGE("%{public}s Low quality use software encode", __func__);
531         return false;
532     }
533     bool isSupportedWithRgba = ImageSystemProperties::GetGenThumbWithGpu() &&
534         pixelMap->GetPixelFormat() == PixelFormat::RGBA_8888;
535     bool isSupport = ImageSystemProperties::GetHardWareEncodeEnabled() && opts.format == "image/jpeg" &&
536         (pixelMap->GetWidth() % 2 == 0) && (pixelMap->GetHeight() % 2 == 0) &&
537         (pixelMap->GetPixelFormat() == PixelFormat::NV12 || pixelMap->GetPixelFormat() == PixelFormat::NV21 ||
538         isSupportedWithRgba) &&
539         pixelMap->GetWidth() <= MAX_IMAGE_SIZE && pixelMap->GetHeight() <= MAX_IMAGE_SIZE &&
540         pixelMap->GetWidth() >= MIN_RGBA_IMAGE_SIZE && pixelMap->GetHeight() >= MIN_RGBA_IMAGE_SIZE;
541     if (!isSupport) {
542         IMAGE_LOGD("hardware encode is not support, dstEncodeFormat:%{public}s, pixelWidth:%{public}d, "
543             "pixelHeight:%{public}d, pixelFormat:%{public}d", opts.format.c_str(), pixelMap->GetWidth(),
544             pixelMap->GetHeight(), pixelMap->GetPixelFormat());
545     }
546     return isSupport;
547 }
548 
DoHardWareEncode(SkWStream * skStream)549 uint32_t ExtEncoder::DoHardWareEncode(SkWStream* skStream)
550 {
551     static ImageFwkExtManager imageFwkExtManager;
552     if (imageFwkExtManager.doHardWareEncodeFunc_ != nullptr || imageFwkExtManager.LoadImageFwkExtNativeSo()) {
553         int32_t retCode = imageFwkExtManager.doHardWareEncodeFunc_(skStream, opts_, pixelmap_);
554         if (retCode == SUCCESS) {
555             IMAGE_LOGD("DoHardWareEncode Success return");
556             return SUCCESS;
557         }
558         IMAGE_LOGE("hardware encode failed, retCode is %{public}d", retCode);
559         ImageInfo imageInfo;
560         pixelmap_->GetImageInfo(imageInfo);
561         ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts_.format, "hardware encode failed");
562     } else {
563         IMAGE_LOGE("hardware encode failed because of load native so failed");
564     }
565     return ERR_IMAGE_ENCODE_FAILED;
566 }
567 
DoEncode(SkWStream * skStream,const SkBitmap & src,const SkEncodedImageFormat & skFormat)568 uint32_t ExtEncoder::DoEncode(SkWStream* skStream, const SkBitmap& src, const SkEncodedImageFormat& skFormat)
569 {
570     ImageFuncTimer imageFuncTimer("%s:(%d, %d)", __func__, pixelmap_->GetWidth(), pixelmap_->GetHeight());
571     ImageInfo imageInfo;
572     pixelmap_->GetImageInfo(imageInfo);
573     if (!SkEncodeImage(skStream, src, skFormat, opts_.quality)) {
574         IMAGE_LOGE("Failed to encode image without exif data");
575         ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts_.format, "Failed to encode image");
576         return ERR_IMAGE_ENCODE_FAILED;
577     }
578     return SUCCESS;
579 }
580 
HardwareEncode(SkWStream & skStream,bool needExif)581 bool ExtEncoder::HardwareEncode(SkWStream &skStream, bool needExif)
582 {
583     uint32_t retCode = ERR_IMAGE_ENCODE_FAILED;
584     if (IsHardwareEncodeSupported(opts_, pixelmap_)) {
585         if (!needExif || pixelmap_->GetExifMetadata() == nullptr ||
586             pixelmap_->GetExifMetadata()->GetExifData() == nullptr) {
587                 retCode = DoHardWareEncode(&skStream);
588                 IMAGE_LOGD("HardwareEncode retCode:%{public}d", retCode);
589                 return (retCode == SUCCESS);
590         }
591         MetadataWStream tStream;
592         retCode = DoHardWareEncode(&tStream);
593         bool cond = retCode != SUCCESS;
594         CHECK_DEBUG_RETURN_RET_LOG(cond, false, "HardwareEncode failed, retCode:%{public}d", retCode);
595         ImageInfo imageInfo;
596         pixelmap_->GetImageInfo(imageInfo);
597         retCode = CreateAndWriteBlob(tStream, pixelmap_, skStream, imageInfo, opts_);
598         IMAGE_LOGD("HardwareEncode retCode :%{public}d", retCode);
599         return (retCode == SUCCESS);
600     }
601     return (retCode == SUCCESS);
602 }
603 
EncodeImageByBitmap(SkBitmap & bitmap,bool needExif,SkWStream & outStream)604 uint32_t ExtEncoder::EncodeImageByBitmap(SkBitmap& bitmap, bool needExif, SkWStream& outStream)
605 {
606     ImageInfo imageInfo;
607     pixelmap_->GetImageInfo(imageInfo);
608     if (!needExif || pixelmap_->GetExifMetadata() == nullptr ||
609         pixelmap_->GetExifMetadata()->GetExifData() == nullptr) {
610             return DoEncode(&outStream, bitmap, encodeFormat_);
611     }
612 
613     MetadataWStream tStream;
614     uint32_t errCode = DoEncode(&tStream, bitmap, encodeFormat_);
615     bool cond = errCode != SUCCESS;
616     CHECK_ERROR_RETURN_RET(cond, errCode);
617     return CreateAndWriteBlob(tStream, pixelmap_, outStream, imageInfo, opts_);
618 }
619 
EncodeImageByPixelMap(PixelMap * pixelMap,bool needExif,SkWStream & outputStream)620 uint32_t ExtEncoder::EncodeImageByPixelMap(PixelMap* pixelMap, bool needExif, SkWStream& outputStream)
621 {
622     if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
623         return EncodeHeifByPixelmap(pixelMap, opts_);
624     }
625     SkBitmap bitmap;
626     TmpBufferHolder holder;
627     SkImageInfo skInfo;
628     ImageData imageData;
629     pixelMap->GetImageInfo(imageData.info);
630     uint32_t width  = static_cast<uint32_t>(imageData.info.size.width);
631     uint32_t height = static_cast<uint32_t>(imageData.info.size.height);
632 
633     bool cond = HardwareEncode(outputStream, needExif) == true;
634     CHECK_DEBUG_RETURN_RET_LOG(cond, SUCCESS, "HardwareEncode Success return");
635     IMAGE_LOGD("HardwareEncode failed or not Supported");
636 
637     std::unique_ptr<uint8_t[]> dstData;
638     uint64_t rowStride = 0;
639     if (IsYuvImage(imageData.info.pixelFormat)) {
640         IMAGE_LOGD("YUV format, convert to RGB");
641         dstData = std::make_unique<uint8_t[]>(width * height * NUM_4);
642         if (YuvToRgbaSkInfo(imageData.info, skInfo, dstData.get(), pixelMap) != SUCCESS) {
643             IMAGE_LOGD("YUV format, convert to RGB fail");
644             return ERR_IMAGE_ENCODE_FAILED;
645         }
646         imageData.pixels = dstData.get();
647         rowStride = skInfo.minRowBytes64();
648     } else {
649         dstData = std::make_unique<uint8_t[]>(width * height * NUM_3);
650         imageData.dst = dstData.get();
651         cond = pixelToSkInfo(imageData, skInfo, pixelMap, holder, encodeFormat_) != SUCCESS;
652         CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED,
653             "ExtEncoder::EncodeImageByPixelMap pixel convert failed");
654         rowStride = skInfo.minRowBytes64();
655 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
656         if (pixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
657             SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*> (pixelMap->GetFd());
658             rowStride = static_cast<uint64_t>(sbBuffer->GetStride());
659             IMAGE_LOGD("rowStride DMA: %{public}llu", static_cast<unsigned long long>(rowStride));
660         }
661 #endif
662     }
663     if (!bitmap.installPixels(skInfo, imageData.pixels, rowStride)) {
664         IMAGE_LOGE("ExtEncoder::EncodeImageByPixelMap to SkBitmap failed");
665         return ERR_IMAGE_ENCODE_FAILED;
666     }
667     return EncodeImageByBitmap(bitmap, needExif, outputStream);
668 }
669 
EncodeHeifByPixelmap(PixelMap * pixelmap,const PlEncodeOptions & opts)670 uint32_t ExtEncoder::EncodeHeifByPixelmap(PixelMap* pixelmap, const PlEncodeOptions& opts)
671 {
672     if (output_ == nullptr) {
673         return ERR_IMAGE_INVALID_PARAMETER;
674     }
675     Media::PixelFormat format = pixelmap->GetPixelFormat();
676     bool cond = format != PixelFormat::RGBA_8888 && format != PixelFormat::NV12 && format != PixelFormat::NV21;
677     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
678         "EncodeHeifByPixelmap, invalid format:%{public}d", format);
679 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) && \
680     defined(HEIF_HW_ENCODE_ENABLE)
681     sptr<SurfaceBuffer> surfaceBuffer;
682     bool needConvertToSurfaceBuffer = pixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
683     if (needConvertToSurfaceBuffer) {
684         surfaceBuffer = ConvertToSurfaceBuffer(pixelmap);
685         cond = surfaceBuffer == nullptr;
686         CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
687             "EncodeHeifByPixelmap ConvertToSurfaceBuffer failed");
688     } else {
689         cond = pixelmap->GetFd() == nullptr;
690         CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeHeifByPixelmap pixelmap get fd failed");
691         surfaceBuffer = sptr<SurfaceBuffer>(reinterpret_cast<SurfaceBuffer*>(pixelmap->GetFd()));
692     }
693     std::vector<ImageItem> inputImgs;
694     std::shared_ptr<ImageItem> primaryItem = AssemblePrimaryImageItem(surfaceBuffer, opts);
695     if (primaryItem == nullptr) {
696         if (needConvertToSurfaceBuffer) {
697             ImageUtils::SurfaceBuffer_Unreference(surfaceBuffer.GetRefPtr());
698         }
699         return ERR_IMAGE_INVALID_PARAMETER;
700     }
701     inputImgs.push_back(*primaryItem);
702     std::vector<MetaItem> inputMetas;
703     std::vector<ItemRef> refs;
704     if (AssembleExifMetaItem(inputMetas)) {
705         AssembleExifRefItem(refs);
706     }
707     uint32_t result = DoHeifEncode(inputImgs, inputMetas, refs);
708     if (needConvertToSurfaceBuffer) {
709         ImageUtils::SurfaceBuffer_Unreference(surfaceBuffer.GetRefPtr());
710     }
711     return result;
712 #endif
713     return ERR_IMAGE_INVALID_PARAMETER;
714 }
715 
RecycleResources()716 void ExtEncoder::RecycleResources()
717 {
718     for (std::shared_ptr<AbsMemory> &memory: tmpMemoryList_) {
719         if (memory == nullptr) {
720             continue;
721         }
722         memory->Release();
723     }
724     tmpMemoryList_.clear();
725 }
726 
727 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
AllocSurfaceBuffer(int32_t width,int32_t height,uint32_t format=GRAPHIC_PIXEL_FMT_RGBA_8888)728 static sptr<SurfaceBuffer> AllocSurfaceBuffer(int32_t width, int32_t height,
729     uint32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888)
730 {
731     sptr<SurfaceBuffer> sb = SurfaceBuffer::Create();
732     BufferRequestConfig requestConfig = {
733         .width = width,
734         .height = height,
735         .strideAlignment = 0x8,
736         .format = format,
737         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
738         .timeout = 0,
739     };
740     GSError ret = sb->Alloc(requestConfig);
741     if (ret != GSERROR_OK) {
742         return nullptr;
743     }
744     void* nativeBuffer = sb.GetRefPtr();
745     int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer);
746     bool cond = err != OHOS::GSERROR_OK;
747     CHECK_ERROR_RETURN_RET(cond, nullptr);
748     return sb;
749 }
750 
ConvertToSurfaceBuffer(PixelMap * pixelmap)751 sptr<SurfaceBuffer> ExtEncoder::ConvertToSurfaceBuffer(PixelMap* pixelmap)
752 {
753     bool cond = pixelmap->GetHeight() <= 0 || pixelmap->GetWidth() <= 0;
754     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
755         "pixelmap height:%{public}d or width:%{public}d error", pixelmap->GetHeight(), pixelmap->GetWidth());
756     uint32_t height = static_cast<uint32_t>(pixelmap->GetHeight());
757     uint32_t width = static_cast<uint32_t>(pixelmap->GetWidth());
758     PixelFormat format = pixelmap->GetPixelFormat();
759     IMAGE_LOGD("ExtEncoder::ConvertToSurfaceBuffer format is %{public}d", format);
760     auto formatSearch = SURFACE_FORMAT_MAP.find(format);
761     cond = formatSearch == SURFACE_FORMAT_MAP.end();
762     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "format:[%{public}d] is not in SURFACE_FORMAT_MAP", format);
763     uint32_t graphicFormat = formatSearch->second;
764     sptr<SurfaceBuffer> surfaceBuffer = AllocSurfaceBuffer(width, height, graphicFormat);
765     cond = surfaceBuffer == nullptr || surfaceBuffer->GetStride() < 0;
766     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "ConvertToSurfaceBuffer surfaceBuffer is nullptr failed");
767     uint32_t dstStride = static_cast<uint32_t>(surfaceBuffer->GetStride());
768     uint8_t* src = const_cast<uint8_t*>(pixelmap->GetPixels());
769     uint8_t* dst = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
770     uint32_t dstSize = surfaceBuffer->GetSize();
771     uint32_t copyHeight = height;
772     uint64_t srcStride = width;
773     if (format == PixelFormat::NV12 || format == PixelFormat::NV21) {
774         const int32_t NUM_2 = 2;
775         copyHeight = height + height / NUM_2;
776         srcStride = width;
777     } else if (format == PixelFormat::RGBA_8888) {
778         copyHeight = height;
779         srcStride = static_cast<uint64_t>(width * NUM_4);
780     }
781     for (uint32_t i = 0; i < copyHeight; i++) {
782         if (memcpy_s(dst, dstSize, src, srcStride) != EOK) {
783             IMAGE_LOGE("ConvertToSurfaceBuffer memcpy failed");
784             ImageUtils::SurfaceBuffer_Unreference(surfaceBuffer.GetRefPtr());
785             return nullptr;
786         }
787         dst += dstStride;
788         dstSize -= dstStride;
789         src += srcStride;
790     }
791     if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
792         GSError err = surfaceBuffer->FlushCache();
793         if (err != GSERROR_OK) {
794             IMAGE_LOGE("FlushCache failed, GSError=%{public}d", err);
795         }
796     }
797     return surfaceBuffer;
798 }
799 
FreeBaseAndGainMapSurfaceBuffer(sptr<SurfaceBuffer> & base,sptr<SurfaceBuffer> & gainMap)800 static void FreeBaseAndGainMapSurfaceBuffer(sptr<SurfaceBuffer>& base, sptr<SurfaceBuffer>& gainMap)
801 {
802     ImageUtils::SurfaceBuffer_Unreference(base.GetRefPtr());
803     ImageUtils::SurfaceBuffer_Unreference(gainMap.GetRefPtr());
804 }
805 
GetHdrMetadata(sptr<SurfaceBuffer> & hdr,sptr<SurfaceBuffer> & gainmap)806 static HdrMetadata GetHdrMetadata(sptr<SurfaceBuffer>& hdr, sptr<SurfaceBuffer>& gainmap)
807 {
808     std::vector<uint8_t> dynamicMetadata = {};
809     VpeUtils::GetSbDynamicMetadata(hdr, dynamicMetadata);
810     std::vector<uint8_t> staticMetadata = {};
811     VpeUtils::GetSbStaticMetadata(hdr, staticMetadata);
812     HdrMetadata metadata = {
813         .staticMetadata = staticMetadata,
814         .dynamicMetadata = dynamicMetadata
815     };
816     std::vector<uint8_t> extendMetadataVec = {};
817     VpeUtils::GetSbDynamicMetadata(gainmap, extendMetadataVec);
818     if (extendMetadataVec.size() != sizeof(HDRVividExtendMetadata)) {
819         metadata.extendMetaFlag = false;
820         return metadata;
821     }
822     if (memcpy_s(&metadata.extendMeta, sizeof(HDRVividExtendMetadata),
823         extendMetadataVec.data(), extendMetadataVec.size()) != EOK) {
824         metadata.extendMetaFlag = false;
825     } else {
826         metadata.extendMetaFlag = true;
827     }
828     return metadata;
829 }
830 
EncodeImageBySurfaceBuffer(sptr<SurfaceBuffer> & surfaceBuffer,SkImageInfo info,bool needExif,SkWStream & outputStream)831 uint32_t ExtEncoder::EncodeImageBySurfaceBuffer(sptr<SurfaceBuffer>& surfaceBuffer, SkImageInfo info,
832     bool needExif, SkWStream& outputStream)
833 {
834     SkBitmap bitmap;
835     ImageInfo imageInfo;
836     uint64_t rowStride = 0;
837     if (surfaceBuffer == nullptr) {
838         IMAGE_LOGE("EncodeImageBySurfaceBuffer failed, surfaceBuffer is nullptr");
839         return ERR_IMAGE_INVALID_PARAMETER;
840     }
841     auto pixels = surfaceBuffer->GetVirAddr();
842     if (pixels == nullptr) {
843         IMAGE_LOGE("EncodeImageBySurfaceBuffer failed, pixels is nullptr");
844         return ERR_IMAGE_INVALID_PARAMETER;
845     }
846     /* do hardwareEncode first, if fail then soft encode*/
847     bool cond = HardwareEncode(outputStream, needExif);
848     CHECK_DEBUG_RETURN_RET_LOG(cond, SUCCESS, "HardwareEncode Success return");
849     IMAGE_LOGD("HardwareEncode failed or not Supported");
850 
851     pixelmap_->GetImageInfo(imageInfo);
852     cond = !PixelYuvUtils::CheckWidthAndHeightMult(imageInfo.size.width, imageInfo.size.height, RGBA_BIT_DEPTH);
853     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
854         "EncodeImageBySurfaceBuffer size overflow width(%{public}d), height(%{public}d)",
855         imageInfo.size.width, imageInfo.size.height);
856     std::unique_ptr<uint8_t[]> dstData;
857     if (IsYuvImage(imageInfo.pixelFormat)) {
858         IMAGE_LOGD("EncodeImageBySurfaceBuffer: YUV format, convert to RGB first");
859         dstData = std::make_unique<uint8_t[]>(imageInfo.size.width * imageInfo.size.height * NUM_4);
860         cond = dstData == nullptr;
861         CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "Memory allocate fail");
862         cond = YuvToRgbaSkInfo(imageInfo, info, dstData.get(), pixelmap_) != SUCCESS;
863         CHECK_DEBUG_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "YUV format, convert to RGB fail");
864         pixels = dstData.get();
865         rowStride = info.minRowBytes64();
866     } else {
867         rowStride = surfaceBuffer->GetStride();
868     }
869     cond = !bitmap.installPixels(info, pixels, rowStride);
870     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED,
871         "ExtEncoder::EncodeImageBySurfaceBuffer to SkBitmap failed");
872     return EncodeImageByBitmap(bitmap, needExif, outputStream);
873 }
874 
GetImageEncodeData(sptr<SurfaceBuffer> & surfaceBuffer,SkImageInfo info,bool needExif)875 sk_sp<SkData> ExtEncoder::GetImageEncodeData(sptr<SurfaceBuffer>& surfaceBuffer, SkImageInfo info, bool needExif)
876 {
877     SkDynamicMemoryWStream stream;
878     if (EncodeImageBySurfaceBuffer(surfaceBuffer, info, needExif, stream) != SUCCESS) {
879         return nullptr;
880     }
881     return stream.detachAsData();
882 }
883 
SetHdrColorSpaceType(sptr<SurfaceBuffer> & surfaceBuffer)884 void ExtEncoder::SetHdrColorSpaceType(sptr<SurfaceBuffer>& surfaceBuffer)
885 {
886     if (pixelmap_ == nullptr) {
887         IMAGE_LOGI("SetHdrColorSpaceType pixelmap_ is nullptr");
888         return;
889     }
890     CM_ColorSpaceType colorspaceType;
891     VpeUtils::GetSbColorSpaceType(surfaceBuffer, colorspaceType);
892     if ((colorspaceType & CM_PRIMARIES_MASK) != COLORPRIMARIES_BT2020) {
893 #ifdef IMAGE_COLORSPACE_FLAG
894         ColorManager::ColorSpaceName colorspace = pixelmap_->InnerGetGrColorSpace().GetColorSpaceName();
895         IMAGE_LOGI("ExtEncoder SetHdrColorSpaceType, color is %{public}d", colorspace);
896         colorspaceType = ColorUtils::ConvertToCMColor(colorspace);
897         VpeUtils::SetSbColorSpaceType(surfaceBuffer, colorspaceType);
898 #endif
899     }
900 }
901 
DecomposeImage(VpeSurfaceBuffers & buffers,HdrMetadata & metadata,bool onlySdr,bool sdrIsSRGB=false)902 static bool DecomposeImage(VpeSurfaceBuffers& buffers, HdrMetadata& metadata, bool onlySdr, bool sdrIsSRGB = false)
903 {
904     VpeUtils::SetSbMetadataType(buffers.sdr, CM_IMAGE_HDR_VIVID_DUAL);
905     VpeUtils::SetSbColorSpaceType(buffers.sdr, sdrIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
906     std::unique_ptr<VpeUtils> utils = std::make_unique<VpeUtils>();
907     int32_t res;
908     if (onlySdr) {
909         bool cond = buffers.hdr == nullptr || buffers.sdr == nullptr;
910         CHECK_ERROR_RETURN_RET(cond, false);
911         res = utils->ColorSpaceConverterImageProcess(buffers.hdr, buffers.sdr);
912     } else {
913         VpeUtils::SetSbMetadataType(buffers.gainmap, CM_METADATA_NONE);
914         VpeUtils::SetSbColorSpaceType(buffers.gainmap, sdrIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
915         res = utils->ColorSpaceConverterDecomposeImage(buffers);
916     }
917     bool cond = res != VPE_ERROR_OK;
918     CHECK_ERROR_RETURN_RET_LOG(cond, false, "DecomposeImage [%{public}d] failed, res = %{public}d", onlySdr, res);
919     if (!onlySdr) {
920         metadata = GetHdrMetadata(buffers.hdr, buffers.gainmap);
921     }
922     return true;
923 }
924 
GetSkInfo(PixelMap * pixelMap,bool isGainmap,bool isSRGB=false)925 static SkImageInfo GetSkInfo(PixelMap* pixelMap, bool isGainmap, bool isSRGB = false)
926 {
927     ImageInfo info;
928     pixelMap->GetImageInfo(info);
929     SkColorType colorType = kRGBA_8888_SkColorType;
930     SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(info.alphaType);
931     if (alphaType == SkAlphaType::kUnknown_SkAlphaType) {
932         alphaType = SkAlphaType::kOpaque_SkAlphaType;
933     }
934     sk_sp<SkColorSpace> colorSpace =
935         SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, isSRGB ? SkNamedGamut::kSRGB : SkNamedGamut::kDisplayP3);
936     int32_t width = info.size.width;
937     int32_t height = info.size.height;
938     if (isGainmap) {
939         const int halfSizeDenominator = 2;
940         width = width / halfSizeDenominator;
941         height = height / halfSizeDenominator;
942 #ifdef IMAGE_COLORSPACE_FLAG
943         if (pixelMap->InnerGetGrColorSpacePtr() != nullptr &&
944             pixelMap->InnerGetGrColorSpace().GetColorSpaceName() != ColorManager::ColorSpaceName::NONE) {
945             colorSpace = pixelMap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
946         }
947         skcms_CICP cicp;
948         ColorUtils::ColorSpaceGetCicp(pixelMap->InnerGetGrColorSpace().GetColorSpaceName(),
949             cicp.colour_primaries, cicp.transfer_characteristics, cicp.matrix_coefficients, cicp.full_range_flag);
950         colorSpace->SetIccCicp(cicp);
951 #endif
952     }
953     return SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
954 }
955 
EncodeSingleVivid(ExtWStream & outputStream)956 uint32_t ExtEncoder::EncodeSingleVivid(ExtWStream& outputStream)
957 {
958     return ERR_IMAGE_INVALID_PARAMETER;
959 }
960 
961 #ifdef HEIF_HW_ENCODE_ENABLE
962 // format: enum + struct
FillLitePropertyItem(std::vector<uint8_t> & properties,size_t & offset,PropertyType type,const void * payloadData,size_t payloadSize)963 static bool FillLitePropertyItem(std::vector<uint8_t>& properties, size_t& offset, PropertyType type,
964     const void* payloadData, size_t payloadSize)
965 {
966     uint8_t* memData = properties.data();
967     bool cond = memData == nullptr;
968     CHECK_ERROR_RETURN_RET_LOG(cond, false, "FillLitePropertyItem memData is nullptr");
969     size_t memSize = properties.size();
970     size_t typeSize = sizeof(type);
971     size_t endOffset = offset + typeSize + payloadSize;
972     cond = endOffset > memSize;
973     CHECK_ERROR_RETURN_RET_LOG(cond, false,
974         "FillLitePropertyItem, endOffset[%{public}ld] over memSize[%{public}ld]", endOffset, memSize);
975     bool res = memcpy_s(memData + offset, memSize - offset, &type, typeSize) == EOK &&
976         memcpy_s(memData + offset + typeSize, memSize - offset - typeSize, payloadData, payloadSize) == EOK;
977     if (res) {
978         offset = endOffset;
979     }
980     return res;
981 }
982 
983 // format: enum + strlen + str
FillLitePropertyItemByString(std::vector<uint8_t> & properties,size_t & offset,PropertyType type,std::string & payloadString)984 static bool FillLitePropertyItemByString(std::vector<uint8_t>& properties, size_t& offset, PropertyType type,
985     std::string& payloadString)
986 {
987     uint8_t* memData = properties.data();
988     bool cond = memData == nullptr;
989     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s memData is nullptr", __func__);
990     size_t memSize = properties.size();
991     cond = payloadString == "";
992     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s failed, payloadString is Null", __func__);
993     size_t lenSize = UINT32_BYTES_NUM;
994     size_t strLen = payloadString.length();
995     size_t typeSize = sizeof(type);
996     size_t endOffset = offset + typeSize + lenSize + strLen;
997     cond = endOffset >= memSize;
998     CHECK_ERROR_RETURN_RET_LOG(cond, false,
999         "%{public}s failed, offset[%{public}ld] over memSize[%{public}ld]", __func__, offset, memSize);
1000     size_t capacitySize = memSize - offset;
1001     const char* payloadData = payloadString.data();
1002     bool res = memcpy_s(memData + offset, capacitySize, &type, typeSize) == EOK &&
1003         memcpy_s(memData + offset + typeSize, capacitySize - typeSize, &strLen, lenSize) == EOK &&
1004         memcpy_s(memData + offset + typeSize + lenSize, capacitySize - typeSize - lenSize, payloadData, strLen) == EOK;
1005     properties[endOffset] = '\0';
1006 
1007     if (res) {
1008         offset = endOffset + PLACE_HOLDER_LENGTH;
1009     }
1010     return res;
1011 }
1012 
AssembleHdrBaseImageItem(sptr<SurfaceBuffer> & surfaceBuffer,ColorManager::ColorSpaceName color,HdrMetadata & metadata,const PlEncodeOptions & opts)1013 std::shared_ptr<ImageItem> ExtEncoder::AssembleHdrBaseImageItem(sptr<SurfaceBuffer>& surfaceBuffer,
1014     ColorManager::ColorSpaceName color, HdrMetadata& metadata, const PlEncodeOptions& opts)
1015 {
1016     bool cond = surfaceBuffer == nullptr;
1017     CHECK_INFO_RETURN_RET_LOG(cond, nullptr, "AssembleHdrBaseImageItem surfaceBuffer is nullptr");
1018     auto item = std::make_shared<ImageItem>();
1019     item->id = PRIMARY_IMAGE_ITEM_ID;
1020     item->isPrimary = true;
1021     item->isHidden = false;
1022     item->compressType = COMPRESS_TYPE_HEVC;
1023     item->quality = opts.quality;
1024     item->pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
1025     item->sharedProperties.fd = -1;
1026     item->pixelSharedBuffer.fd = -1;
1027     ColourInfo colorInfo;
1028     GetColourInfo(color, colorInfo);
1029     ContentLightLevel light;
1030     MasteringDisplayColourVolume colour;
1031     bool hasLight = GetStaticMetadata(metadata, colour, light);
1032     uint32_t propertiesSize = 0;
1033     propertiesSize +=
1034         (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType) + sizeof(PropertyType::COLOR_INFO) + sizeof(ColourInfo));
1035     if (hasLight) {
1036         propertiesSize += (sizeof(PropertyType::CONTENT_LIGHT_LEVEL) + sizeof(ContentLightLevel));
1037     }
1038     item->liteProperties.resize(propertiesSize);
1039     size_t offset = 0;
1040     if (!FillNclxColorProperty(item, offset, colorInfo)) {
1041         return nullptr;
1042     }
1043     if (hasLight && (!FillLitePropertyItem(item->liteProperties, offset,
1044         PropertyType::CONTENT_LIGHT_LEVEL, &colour, sizeof(ContentLightLevel)))) {
1045         return nullptr;
1046     }
1047     return item;
1048 }
1049 
AssembleGainmapImageItem(sptr<SurfaceBuffer> & surfaceBuffer,ColorManager::ColorSpaceName color,const PlEncodeOptions & opts)1050 std::shared_ptr<ImageItem> ExtEncoder::AssembleGainmapImageItem(sptr<SurfaceBuffer>& surfaceBuffer,
1051     ColorManager::ColorSpaceName color, const PlEncodeOptions &opts)
1052 {
1053     bool cond = surfaceBuffer == nullptr;
1054     CHECK_INFO_RETURN_RET_LOG(cond, nullptr, "AssembleGainmapImageItem surfacebuffer is nullptr");
1055     auto item = std::make_shared<ImageItem>();
1056     item->id = GAINMAP_IMAGE_ITEM_ID;
1057     item->itemName = GAINMAP_IMAGE_ITEM_NAME;
1058     item->isPrimary = false;
1059     item->isHidden = true;
1060     item->compressType = COMPRESS_TYPE_HEVC;
1061     item->quality = opts.quality;
1062     item->sharedProperties.fd = -1;
1063     item->pixelSharedBuffer.fd = -1;
1064     item->pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
1065     ColourInfo colorInfo;
1066     GetColourInfo(color, colorInfo);
1067     uint32_t propertiesSize = 0;
1068     propertiesSize +=
1069         (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType) + sizeof(PropertyType::COLOR_INFO) + sizeof(ColourInfo));
1070     item->liteProperties.resize(propertiesSize);
1071     size_t offset = 0;
1072     cond = !FillNclxColorProperty(item, offset, colorInfo);
1073     CHECK_ERROR_RETURN_RET(cond, nullptr);
1074     return item;
1075 }
1076 
AssembleHeifHdrPicture(sptr<SurfaceBuffer> & mainSptr,bool sdrIsSRGB,std::vector<ImageItem> & inputImgs)1077 uint32_t ExtEncoder::AssembleHeifHdrPicture(
1078     sptr<SurfaceBuffer>& mainSptr, bool sdrIsSRGB, std::vector<ImageItem>& inputImgs)
1079 {
1080     auto gainPixelMap = picture_->GetGainmapPixelMap();
1081     bool cond = gainPixelMap == nullptr || gainPixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1082     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1083         "%{public}s, the gainPixelMap is nullptr or gainPixelMap is nonDMA", __func__);
1084     sptr<SurfaceBuffer> gainMapSptr(reinterpret_cast<SurfaceBuffer*>(gainPixelMap->GetFd()));
1085     HdrMetadata metadata = GetHdrMetadata(mainSptr, gainMapSptr);
1086 
1087     ColorManager::ColorSpaceName colorspaceName =
1088         sdrIsSRGB ? ColorManager::ColorSpaceName::SRGB : ColorManager::ColorSpaceName::DISPLAY_P3;
1089     std::shared_ptr<ImageItem> primaryItem = AssembleHdrBaseImageItem(mainSptr, colorspaceName, metadata, opts_);
1090     cond = primaryItem == nullptr;
1091     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s, get primary image failed", __func__);
1092     inputImgs.push_back(*primaryItem);
1093     std::shared_ptr<ImageItem> gainmapItem = AssembleGainmapImageItem(gainMapSptr, colorspaceName, opts_);
1094     cond = gainmapItem == nullptr;
1095     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1096         "%{public}s, get gainmap image item failed", __func__);
1097     inputImgs.push_back(*gainmapItem);
1098     ColorManager::ColorSpaceName tmapColor = picture_->GetMainPixel()->InnerGetGrColorSpace().GetColorSpaceName();
1099     std::shared_ptr<ImageItem> tmapItem = AssembleTmapImageItem(tmapColor, metadata, opts_);
1100     cond = tmapItem == nullptr;
1101     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s, get tmap image item failed", __func__);
1102     inputImgs.push_back(*tmapItem);
1103     return SUCCESS;
1104 }
1105 
AssembleSdrImageItem(sptr<SurfaceBuffer> & surfaceBuffer,SkImageInfo sdrInfo,std::vector<ImageItem> & inputImgs)1106 uint32_t ExtEncoder::AssembleSdrImageItem(
1107     sptr<SurfaceBuffer>& surfaceBuffer, SkImageInfo sdrInfo, std::vector<ImageItem>& inputImgs)
1108 {
1109     bool cond = surfaceBuffer == nullptr;
1110     CHECK_INFO_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s surfaceBuffer is nullptr", __func__);
1111     ImageItem item;
1112     sk_sp<SkData> iccProfile = icc_from_color_space(sdrInfo);
1113     cond = !AssembleICCImageProperty(iccProfile, item.sharedProperties);
1114     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1115         "%{public}s AssembleICCImageProperty failed", __func__);
1116     item.id = PRIMARY_IMAGE_ITEM_ID;
1117     item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
1118     item.isPrimary = true;
1119     item.isHidden = false;
1120     item.compressType = COMPRESS_TYPE_HEVC;
1121     item.quality = opts_.quality;
1122     uint32_t litePropertiesSize = (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1123     item.liteProperties.resize(litePropertiesSize);
1124     size_t offset = 0;
1125     ColorType colorType = ColorType::RICC;
1126     cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1127     CHECK_INFO_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1128     inputImgs.push_back(item);
1129     return SUCCESS;
1130 }
1131 
AssembleHeifAuxiliaryPicture(std::vector<ImageItem> & inputImgs,std::vector<ItemRef> & refs)1132 uint32_t ExtEncoder::AssembleHeifAuxiliaryPicture(std::vector<ImageItem>& inputImgs, std::vector<ItemRef>& refs)
1133 {
1134     bool cond = !picture_;
1135     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "picture_ is nullptr");
1136     if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::DEPTH_MAP) &&
1137         AssembleHeifAuxiliaryNoncodingMap(inputImgs, AuxiliaryPictureType::DEPTH_MAP) == SUCCESS) {
1138         AssembleAuxiliaryRefItem(AuxiliaryPictureType::DEPTH_MAP, refs);
1139     }
1140     if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::UNREFOCUS_MAP) &&
1141         AssembleHeifUnrefocusMap(inputImgs) == SUCCESS) {
1142         AssembleAuxiliaryRefItem(AuxiliaryPictureType::UNREFOCUS_MAP, refs);
1143     }
1144     if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::LINEAR_MAP) &&
1145         AssembleHeifAuxiliaryNoncodingMap(inputImgs, AuxiliaryPictureType::LINEAR_MAP) == SUCCESS) {
1146         AssembleAuxiliaryRefItem(AuxiliaryPictureType::LINEAR_MAP, refs);
1147     }
1148     if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP) &&
1149         AssembleHeifFragmentMap(inputImgs) == SUCCESS) {
1150         AssembleAuxiliaryRefItem(AuxiliaryPictureType::FRAGMENT_MAP, refs);
1151     }
1152     return SUCCESS;
1153 }
1154 
InitAuxiliaryImageItem(uint32_t id,std::string itemName)1155 ImageItem ExtEncoder::InitAuxiliaryImageItem(uint32_t id, std::string itemName)
1156 {
1157     ImageItem item;
1158     item.id = id;
1159     item.itemName = itemName;
1160     item.isPrimary = false;
1161     item.isHidden = true;
1162     item.quality = opts_.quality;
1163     item.sharedProperties.fd = -1;
1164     item.pixelSharedBuffer.fd = -1;
1165     if (id == DEPTH_MAP_ITEM_ID || id == LINEAR_MAP_ITEM_ID) {
1166         item.compressType = COMPRESS_TYPE_NONE;
1167     } else {
1168         item.compressType = COMPRESS_TYPE_HEVC;
1169     }
1170     return item;
1171 }
1172 
GetHeifEncodeItemInfo(AuxiliaryPictureType auxType)1173 HeifEncodeItemInfo GetHeifEncodeItemInfo(AuxiliaryPictureType auxType)
1174 {
1175     HeifEncodeItemInfo itemInfo;
1176     switch (auxType) {
1177         case AuxiliaryPictureType::GAINMAP:
1178             itemInfo.itemId = GAINMAP_IMAGE_ITEM_ID;
1179             itemInfo.itemName = GAINMAP_IMAGE_ITEM_NAME;
1180             itemInfo.itemType = HEIF_AUXTTYPE_ID_GAINMAP;
1181             break;
1182         case AuxiliaryPictureType::DEPTH_MAP:
1183             itemInfo.itemId = DEPTH_MAP_ITEM_ID;
1184             itemInfo.itemName = DEPTH_MAP_ITEM_NAME;
1185             itemInfo.itemType = HEIF_AUXTTYPE_ID_DEPTH_MAP;
1186             break;
1187         case AuxiliaryPictureType::UNREFOCUS_MAP:
1188             itemInfo.itemId = UNREFOCUS_MAP_ITEM_ID;
1189             itemInfo.itemName = UNREFOCUS_MAP_ITEM_NAME;
1190             itemInfo.itemType = HEIF_AUXTTYPE_ID_UNREFOCUS_MAP;
1191             break;
1192         case AuxiliaryPictureType::LINEAR_MAP:
1193             itemInfo.itemId = LINEAR_MAP_ITEM_ID;
1194             itemInfo.itemName = LINEAR_MAP_ITEM_NAME;
1195             itemInfo.itemType = HEIF_AUXTTYPE_ID_LINEAR_MAP;
1196             break;
1197         case AuxiliaryPictureType::FRAGMENT_MAP:
1198             itemInfo.itemId = FRAGMENT_MAP_ITEM_ID;
1199             itemInfo.itemName = FRAGMENT_MAP_ITEM_NAME;
1200             itemInfo.itemType = HEIF_AUXTTYPE_ID_FRAGMENT_MAP;
1201             break;
1202         default:
1203             break;
1204     }
1205     return itemInfo;
1206 }
1207 
AssembleHeifAuxiliaryNoncodingMap(std::vector<ImageItem> & inputImgs,AuxiliaryPictureType auxType)1208 uint32_t ExtEncoder::AssembleHeifAuxiliaryNoncodingMap(std::vector<ImageItem>& inputImgs, AuxiliaryPictureType auxType)
1209 {
1210     auto auxMap = picture_->GetAuxiliaryPicture(auxType);
1211     if (!auxMap || !auxMap->GetContentPixel() ||
1212         auxMap->GetContentPixel()->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
1213         IMAGE_LOGE("%{public}s The auxMap is nullptr or allocator type is not DMA_ALLOC", __func__);
1214         return ERR_IMAGE_INVALID_PARAMETER;
1215     }
1216     sptr<SurfaceBuffer> auxMapSptr(reinterpret_cast<SurfaceBuffer*>(auxMap->GetContentPixel()->GetFd()));
1217     bool cond = !auxMapSptr;
1218     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s auxMapSptr is nullptr", __func__);
1219 
1220     HeifEncodeItemInfo itemInfo = GetHeifEncodeItemInfo(auxType);
1221     auto item = InitAuxiliaryImageItem(itemInfo.itemId, itemInfo.itemName);
1222     std::string auxTypeStr = itemInfo.itemType;
1223     Resolution resolution = {
1224         auxMap->GetContentPixel()->GetWidth(),
1225         auxMap->GetContentPixel()->GetHeight()
1226     };
1227     uint32_t litePropertiesSize =
1228         sizeof(PropertyType::AUX_TYPE) + UINT32_BYTES_NUM + auxTypeStr.length() + PLACE_HOLDER_LENGTH;
1229     litePropertiesSize += (sizeof(PropertyType::IMG_RESOLUTION) + sizeof(Resolution));
1230     size_t offset = 0;
1231     item.liteProperties.resize(litePropertiesSize);
1232     cond = !FillLitePropertyItemByString(item.liteProperties, offset, PropertyType::AUX_TYPE, auxTypeStr);
1233     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1234     cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::IMG_RESOLUTION, &resolution,
1235         sizeof(Resolution));
1236     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1237     uint32_t capacity = auxMap->GetContentPixel()->GetCapacity();
1238     cond = !FillPixelSharedBuffer(auxMapSptr, capacity, item.pixelSharedBuffer);
1239     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1240         "%{public}s Fill pixel shared buffer failed", __func__);
1241     inputImgs.push_back(item);
1242     return SUCCESS;
1243 }
1244 
AssembleHeifUnrefocusMap(std::vector<ImageItem> & inputImgs)1245 uint32_t ExtEncoder::AssembleHeifUnrefocusMap(std::vector<ImageItem>& inputImgs)
1246 {
1247     auto unrefocusMap = picture_->GetAuxiliaryPicture(AuxiliaryPictureType::UNREFOCUS_MAP);
1248     bool cond = !unrefocusMap || !unrefocusMap->GetContentPixel() ||
1249         unrefocusMap->GetContentPixel()->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1250     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1251         "%{public}s The unrefocusMap is nullptr or allocator type is not DMA_ALLOC", __func__);
1252     HeifEncodeItemInfo itemInfo = GetHeifEncodeItemInfo(AuxiliaryPictureType::UNREFOCUS_MAP);
1253     auto item = InitAuxiliaryImageItem(itemInfo.itemId, itemInfo.itemName);
1254     bool sdrIsSRGB = unrefocusMap->GetContentPixel()->GetToSdrColorSpaceIsSRGB();
1255     SkImageInfo unrefocusInfo = GetSkInfo(unrefocusMap->GetContentPixel().get(), false, sdrIsSRGB);
1256     sk_sp<SkData> iccProfile = icc_from_color_space(unrefocusInfo);
1257     cond = !AssembleICCImageProperty(iccProfile, item.sharedProperties);
1258     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1259         "%{public}s AssembleICCImageProperty failed", __func__);
1260     sptr<SurfaceBuffer> unrefocusMapSptr(reinterpret_cast<SurfaceBuffer*>(unrefocusMap->GetContentPixel()->GetFd()));
1261     cond = !unrefocusMapSptr;
1262     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s unrefocusMapSptr is nullptr", __func__);
1263     item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(unrefocusMapSptr->GetBufferHandle());
1264     std::string auxTypeStr = itemInfo.itemType;
1265 
1266     uint32_t litePropertiesSize =
1267         sizeof(PropertyType::AUX_TYPE) + UINT32_BYTES_NUM + auxTypeStr.length() + PLACE_HOLDER_LENGTH;
1268     litePropertiesSize += (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1269     item.liteProperties.resize(litePropertiesSize);
1270     size_t offset = 0;
1271     cond = !FillLitePropertyItemByString(item.liteProperties, offset, PropertyType::AUX_TYPE, auxTypeStr);
1272     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1273     ColorType colorType = ColorType::RICC;
1274     cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1275     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1276     inputImgs.push_back(item);
1277     return SUCCESS;
1278 }
1279 
GetFragmentRelLocation(std::shared_ptr<AuxiliaryPicture> & fragmentMap)1280 RelativeLocation GetFragmentRelLocation(std::shared_ptr<AuxiliaryPicture> &fragmentMap)
1281 {
1282     RelativeLocation loc;
1283     auto fragmentMeta = fragmentMap->GetMetadata(MetadataType::FRAGMENT);
1284     bool cond = fragmentMeta == nullptr;
1285     CHECK_ERROR_RETURN_RET_LOG(cond, loc, "The fragmentMap has not fragmentMap");
1286     std::string loc_x = "";
1287     std::string loc_y = "";
1288     uint32_t horizontalOffset = 0;
1289     uint32_t verticalOffset = 0;
1290     fragmentMeta->GetValue(FRAGMENT_METADATA_KEY_X, loc_x);
1291     fragmentMeta->GetValue(FRAGMENT_METADATA_KEY_Y, loc_y);
1292     ImageUtils::StrToUint32(loc_x, horizontalOffset);
1293     ImageUtils::StrToUint32(loc_y, verticalOffset);
1294     loc.horizontalOffset = horizontalOffset;
1295     loc.verticalOffset = verticalOffset;
1296     return loc;
1297 }
1298 
AssembleHeifFragmentMap(std::vector<ImageItem> & inputImgs)1299 uint32_t ExtEncoder::AssembleHeifFragmentMap(std::vector<ImageItem>& inputImgs)
1300 {
1301     auto fragmentMap = picture_->GetAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP);
1302     bool cond = !fragmentMap || !fragmentMap->GetContentPixel() ||
1303         fragmentMap->GetContentPixel()->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1304     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1305         "%{public}s The fragmentMap is nullptr or allocator type is not DMA_ALLOC", __func__);
1306     sptr<SurfaceBuffer> fragmentMapSptr(reinterpret_cast<SurfaceBuffer*>(fragmentMap->GetContentPixel()->GetFd()));
1307     cond = !fragmentMapSptr;
1308     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s fragmentMapSptr is nullptr", __func__);
1309     HeifEncodeItemInfo itemInfo = GetHeifEncodeItemInfo(AuxiliaryPictureType::FRAGMENT_MAP);
1310     auto item = InitAuxiliaryImageItem(itemInfo.itemId, itemInfo.itemName);
1311     bool sdrIsSRGB = fragmentMap->GetContentPixel()->GetToSdrColorSpaceIsSRGB();
1312     SkImageInfo fragmentInfo = GetSkInfo(fragmentMap->GetContentPixel().get(), false, sdrIsSRGB);
1313     sk_sp<SkData> iccProfile = icc_from_color_space(fragmentInfo);
1314     cond = !AssembleICCImageProperty(iccProfile, item.sharedProperties);
1315     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1316         "%{public}s AssembleICCImageProperty failed", __func__);
1317     item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(fragmentMapSptr->GetBufferHandle());
1318     std::string auxTypeStr = itemInfo.itemType;
1319     uint32_t litePropertiesSize =
1320         sizeof(PropertyType::AUX_TYPE) + UINT32_BYTES_NUM + auxTypeStr.length() + PLACE_HOLDER_LENGTH;
1321     litePropertiesSize += (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1322     litePropertiesSize += (sizeof(PropertyType::RLOC_INFO) + sizeof(RelativeLocation));
1323     item.liteProperties.resize(litePropertiesSize);
1324     size_t offset = 0;
1325     ColorType colorType = ColorType::RICC;
1326     cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1327     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1328     cond = !FillLitePropertyItemByString(item.liteProperties, offset, PropertyType::AUX_TYPE, auxTypeStr);
1329     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1330     RelativeLocation loc = GetFragmentRelLocation(fragmentMap);
1331     cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::RLOC_INFO, &loc, sizeof(RelativeLocation));
1332     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1333     inputImgs.push_back(item);
1334     return SUCCESS;
1335 }
1336 #endif
1337 
EncodeDualVivid(ExtWStream & outputStream)1338 uint32_t ExtEncoder::EncodeDualVivid(ExtWStream& outputStream)
1339 {
1340     IMAGE_LOGD("ExtEncoder::EncodeDualVivid");
1341     if (!pixelmap_->IsHdr() ||
1342         pixelmap_->GetAllocatorType() != AllocatorType::DMA_ALLOC ||
1343         (encodeFormat_ != SkEncodedImageFormat::kJPEG && encodeFormat_ != SkEncodedImageFormat::kHEIF)) {
1344         return ERR_IMAGE_INVALID_PARAMETER;
1345     }
1346     bool sdrIsSRGB = pixelmap_->GetToSdrColorSpaceIsSRGB();
1347     SkImageInfo baseInfo = GetSkInfo(pixelmap_, false, sdrIsSRGB);
1348     SkImageInfo gainmapInfo = GetSkInfo(pixelmap_, true, sdrIsSRGB);
1349     sptr<SurfaceBuffer> baseSptr = AllocSurfaceBuffer(baseInfo.width(), baseInfo.height());
1350     sptr<SurfaceBuffer> gainMapSptr = AllocSurfaceBuffer(gainmapInfo.width(), gainmapInfo.height());
1351     bool cond = baseSptr == nullptr || gainMapSptr == nullptr;
1352     CHECK_ERROR_RETURN_RET(cond, IMAGE_RESULT_CREATE_SURFAC_FAILED);
1353     HdrMetadata metadata;
1354     sptr<SurfaceBuffer> hdrSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (pixelmap_->GetFd()));
1355     SetHdrColorSpaceType(hdrSurfaceBuffer);
1356     CM_HDR_Metadata_Type hdrMetadataType;
1357     VpeUtils::GetSbMetadataType(hdrSurfaceBuffer, hdrMetadataType);
1358     VpeUtils::SetSbMetadataType(hdrSurfaceBuffer, CM_IMAGE_HDR_VIVID_SINGLE);
1359     VpeSurfaceBuffers buffers = {
1360         .sdr = baseSptr,
1361         .gainmap = gainMapSptr,
1362         .hdr = hdrSurfaceBuffer,
1363     };
1364     if (!DecomposeImage(buffers, metadata, false, sdrIsSRGB)) {
1365         IMAGE_LOGE("EncodeDualVivid decomposeImage failed");
1366         FreeBaseAndGainMapSurfaceBuffer(baseSptr, gainMapSptr);
1367         return IMAGE_RESULT_CREATE_SURFAC_FAILED;
1368     }
1369     metadata.hdrMetadataType = static_cast<int32_t>(hdrMetadataType);
1370     uint32_t error;
1371     if (encodeFormat_ == SkEncodedImageFormat::kJPEG) {
1372         sk_sp<SkData> baseImageData = GetImageEncodeData(baseSptr, baseInfo, opts_.needsPackProperties);
1373         sk_sp<SkData> gainMapImageData = GetImageEncodeData(gainMapSptr, gainmapInfo, false);
1374         error = HdrJpegPackerHelper::SpliceHdrStream(baseImageData, gainMapImageData, outputStream, metadata);
1375     } else if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1376         error = EncodeHeifDualHdrImage(baseSptr, gainMapSptr, metadata);
1377     } else {
1378         error = ERR_IMAGE_INVALID_PARAMETER;
1379     }
1380     FreeBaseAndGainMapSurfaceBuffer(baseSptr, gainMapSptr);
1381     return error;
1382 }
1383 
EncodeSdrImage(ExtWStream & outputStream)1384 uint32_t ExtEncoder::EncodeSdrImage(ExtWStream& outputStream)
1385 {
1386     IMAGE_LOGD("ExtEncoder EncodeSdrImage");
1387     if (!pixelmap_->IsHdr()) {
1388         return EncodeImageByPixelMap(pixelmap_, opts_.needsPackProperties, outputStream);
1389     }
1390     bool cond = pixelmap_->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1391     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "pixelmap is 10bit, but not dma buffer");
1392     ImageInfo info;
1393     pixelmap_->GetImageInfo(info);
1394     bool sdrIsSRGB = pixelmap_->GetToSdrColorSpaceIsSRGB();
1395     SkImageInfo baseInfo = GetSkInfo(pixelmap_, false, sdrIsSRGB);
1396     sptr<SurfaceBuffer> baseSptr = AllocSurfaceBuffer(baseInfo.width(), baseInfo.height());
1397     VpeUtils::SetSbMetadataType(baseSptr, CM_IMAGE_HDR_VIVID_DUAL);
1398     VpeUtils::SetSbColorSpaceType(baseSptr, CM_SRGB_FULL);
1399     cond = baseSptr == nullptr;
1400     CHECK_ERROR_RETURN_RET_LOG(cond, IMAGE_RESULT_CREATE_SURFAC_FAILED, "EncodeSdrImage sdr buffer alloc failed");
1401     sptr<SurfaceBuffer> hdrSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(pixelmap_->GetFd()));
1402     VpeUtils::SetSbMetadataType(hdrSurfaceBuffer, CM_IMAGE_HDR_VIVID_SINGLE);
1403     SetHdrColorSpaceType(hdrSurfaceBuffer);
1404     VpeSurfaceBuffers buffers = {
1405         .sdr = baseSptr,
1406         .hdr = hdrSurfaceBuffer,
1407     };
1408     HdrMetadata metadata;
1409     if (!DecomposeImage(buffers, metadata, true, sdrIsSRGB)) {
1410         IMAGE_LOGE("EncodeSdrImage decomposeImage failed");
1411         ImageUtils::SurfaceBuffer_Unreference(baseSptr.GetRefPtr());
1412         return IMAGE_RESULT_CREATE_SURFAC_FAILED;
1413     }
1414     uint32_t error;
1415     if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1416         error = EncodeHeifSdrImage(baseSptr, baseInfo);
1417     } else {
1418         error = EncodeImageBySurfaceBuffer(baseSptr, baseInfo, opts_.needsPackProperties, outputStream);
1419     }
1420     ImageUtils::SurfaceBuffer_Unreference(baseSptr.GetRefPtr());
1421     return error;
1422 }
1423 
EncodeHeifDualHdrImage(sptr<SurfaceBuffer> & sdr,sptr<SurfaceBuffer> & gainmap,Media::HdrMetadata & metadata,bool sdrIsSRGB)1424 uint32_t ExtEncoder::EncodeHeifDualHdrImage(sptr<SurfaceBuffer>& sdr, sptr<SurfaceBuffer>& gainmap,
1425     Media::HdrMetadata& metadata, bool sdrIsSRGB)
1426 {
1427 #ifdef HEIF_HW_ENCODE_ENABLE
1428     std::vector<ImageItem> inputImgs;
1429     ColorSpaceManager colorspaceName =
1430         sdrIsSRGB ? ColorManager::ColorSpaceName::SRGB : ColorManager::ColorSpaceName::DISPLAY_P3;
1431     std::shared_ptr<ImageItem> primaryItem =
1432         AssembleHdrBaseImageItem(sdr, colorspaceName, metadata, opts_);
1433     bool cond = primaryItem == nullptr;
1434     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "AssmbleHeifDualHdrImage, get primary image failed");
1435     inputImgs.push_back(*primaryItem);
1436     std::shared_ptr<ImageItem> gainmapItem =
1437         AssembleGainmapImageItem(gainmap, colorspaceName, opts_);
1438     cond = gainmapItem == nullptr;
1439     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1440         "AssembleDualHdrImage, get gainmap image item failed");
1441     inputImgs.push_back(*gainmapItem);
1442     ColorManager::ColorSpaceName tmapColor = pixelmap_->InnerGetGrColorSpace().GetColorSpaceName();
1443     std::shared_ptr<ImageItem> tmapItem = AssembleTmapImageItem(tmapColor, metadata, opts_);
1444     cond = tmapItem == nullptr;
1445     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "AssembleDualHdrImage, get tmap image item failed");
1446     inputImgs.push_back(*tmapItem);
1447     std::vector<MetaItem> inputMetas;
1448     std::vector<ItemRef> refs;
1449     if (AssembleExifMetaItem(inputMetas)) {
1450         AssembleExifRefItem(refs);
1451     }
1452     AssembleDualHdrRefItem(refs);
1453     return DoHeifEncode(inputImgs, inputMetas, refs);
1454 #else
1455     return ERR_IMAGE_INVALID_PARAMETER;
1456 #endif
1457 }
1458 
EncodeHeifSdrImage(sptr<SurfaceBuffer> & sdr,SkImageInfo sdrInfo)1459 uint32_t ExtEncoder::EncodeHeifSdrImage(sptr<SurfaceBuffer>& sdr, SkImageInfo sdrInfo)
1460 {
1461 #ifdef HEIF_HW_ENCODE_ENABLE
1462     bool cond = sdr == nullptr;
1463     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeHeifSdrImage, sdr surfacebuffer is nullptr");
1464     ImageItem item;
1465     item.id = PRIMARY_IMAGE_ITEM_ID;
1466     item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(sdr->GetBufferHandle());
1467     item.isPrimary = true;
1468     item.isHidden = false;
1469     item.compressType = COMPRESS_TYPE_HEVC;
1470     item.quality = opts_.quality;
1471     item.sharedProperties.fd = -1;
1472     item.pixelSharedBuffer.fd = -1;
1473     ImageInfo info;
1474     pixelmap_->GetImageInfo(info);
1475     sk_sp<SkData> iccProfile = icc_from_color_space(sdrInfo);
1476     bool tempRes = AssembleICCImageProperty(iccProfile, item.sharedProperties);
1477     cond = !tempRes;
1478     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeSdrImage AssembleICCImageProperty failed");
1479     uint32_t litePropertiesSize = (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1480     item.liteProperties.resize(litePropertiesSize);
1481     size_t offset = 0;
1482     ColorType colorType = ColorType::RICC;
1483     cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1484     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeHeifSdrImage Fill color type failed");
1485     std::vector<ImageItem> inputImgs;
1486     inputImgs.push_back(item);
1487     std::vector<MetaItem> inputMetas;
1488     std::vector<ItemRef> refs;
1489     if (AssembleExifMetaItem(inputMetas)) {
1490         AssembleExifRefItem(refs);
1491     }
1492     return DoHeifEncode(inputImgs, inputMetas, refs);
1493 #else
1494     return ERR_IMAGE_INVALID_PARAMETER;
1495 #endif
1496 }
1497 
EncodePicture()1498 uint32_t ExtEncoder::EncodePicture()
1499 {
1500     bool cond = (encodeFormat_ != SkEncodedImageFormat::kJPEG && encodeFormat_ != SkEncodedImageFormat::kHEIF);
1501     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1502         "%{public}s: unsupported encode format: %{public}s", __func__, opts_.format.c_str());
1503     if (opts_.isEditScene && encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1504         return EncodeEditScenePicture();
1505     }
1506     if (encodeFormat_ == SkEncodedImageFormat::kJPEG) {
1507         CheckJpegAuxiliaryTagName();
1508     }
1509     ExtWStream wStream(output_);
1510     return EncodeCameraScenePicture(wStream);
1511 }
1512 
IsValidSizeForHardwareEncode(int32_t width,int32_t height)1513 static bool IsValidSizeForHardwareEncode(int32_t width, int32_t height)
1514 {
1515     if (ImageUtils::IsEven(width) && ImageUtils::IsInRange(width, MIN_IMAGE_SIZE, MAX_IMAGE_SIZE) &&
1516         ImageUtils::IsEven(height) && ImageUtils::IsInRange(height, MIN_IMAGE_SIZE, MAX_IMAGE_SIZE)) {
1517         return true;
1518     }
1519     IMAGE_LOGD("%{public}s hardware encode is not support, width: %{public}d, height: %{public}d",
1520         __func__, width, height);
1521     return false;
1522 }
1523 
IsPictureSupportHardwareEncode()1524 bool ExtEncoder::IsPictureSupportHardwareEncode()
1525 {
1526     bool cond = !ImageSystemProperties::GetHardWareEncodeEnabled();
1527     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s hardware encode disabled", __func__);
1528     cond = picture_ == nullptr;
1529     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s picture is null", __func__);
1530 
1531     if (opts_.quality < LOW_QUALITY_BOUNDARY) {
1532         IMAGE_LOGE("%{public}s Low quality use jpeg software encode", __func__);
1533         return false;
1534     }
1535     auto mainPixelMap = picture_->GetMainPixel();
1536     if (mainPixelMap == nullptr ||
1537         !IsValidSizeForHardwareEncode(mainPixelMap->GetWidth(), mainPixelMap->GetHeight())) {
1538         IMAGE_LOGI("%{public}s MainPixelMap not support hardware encode", __func__);
1539         return false;
1540     }
1541 
1542     const auto& auxTypes = ImageUtils::GetAllAuxiliaryPictureType();
1543     for (const auto& auxType : auxTypes) {
1544         auto auxPicture = picture_->GetAuxiliaryPicture(auxType);
1545         if (auxPicture == nullptr) {
1546             continue;
1547         }
1548         auto auxPixelMap = auxPicture->GetContentPixel();
1549         if (auxPixelMap == nullptr) {
1550             continue;
1551         }
1552         cond = !IsValidSizeForHardwareEncode(auxPixelMap->GetWidth(), auxPixelMap->GetHeight());
1553         CHECK_INFO_RETURN_RET_LOG(cond, false,
1554             "%{public}s auxType: %{public}d not support hardware encode", __func__, auxType);
1555     }
1556     return true;
1557 }
1558 
TryHardwareEncodePicture(SkWStream & skStream,std::string & errorMsg)1559 uint32_t ExtEncoder::TryHardwareEncodePicture(SkWStream& skStream, std::string& errorMsg)
1560 {
1561     errorMsg = "Hardware encode picture failed";
1562     if (picture_ == nullptr) {
1563         errorMsg = "picture is nullptr";
1564         return ERR_IMAGE_DATA_ABNORMAL;
1565     }
1566     static ImageFwkExtManager imageFwkExtManager;
1567     if (!imageFwkExtManager.LoadImageFwkExtNativeSo() || imageFwkExtManager.doHardwareEncodePictureFunc_ == nullptr) {
1568         errorMsg = "Load hardware encode library failed";
1569         return ERR_IMAGE_ENCODE_FAILED;
1570     }
1571     return imageFwkExtManager.doHardwareEncodePictureFunc_(&skStream, opts_, picture_);
1572 }
1573 
EncodeCameraScenePicture(SkWStream & skStream)1574 uint32_t ExtEncoder::EncodeCameraScenePicture(SkWStream& skStream)
1575 {
1576     uint32_t retCode = ERR_IMAGE_ENCODE_FAILED;
1577     std::string errorMsg = "Unknown encode failed";
1578     if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1579         retCode = TryHardwareEncodePicture(skStream, errorMsg);
1580     } else if (encodeFormat_ == SkEncodedImageFormat::kJPEG) {
1581         if (IsPictureSupportHardwareEncode()) {
1582             retCode = TryHardwareEncodePicture(skStream, errorMsg);
1583         } else {
1584             errorMsg = "Not support hardware encode";
1585         }
1586         if (retCode != SUCCESS) {
1587             IMAGE_LOGW("%{public}s, retCode is: %{public}d, try jpeg software encode", errorMsg.c_str(), retCode);
1588             retCode = EncodeJpegPicture(skStream);
1589             errorMsg = "Jpeg software encode picture failed";
1590         }
1591     }
1592     if (retCode != SUCCESS) {
1593         ImageInfo imageInfo;
1594         picture_->GetMainPixel()->GetImageInfo(imageInfo);
1595         IMAGE_LOGE("%{public}s, retCode is: %{public}d", errorMsg.c_str(), retCode);
1596         ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts_.format, errorMsg);
1597     }
1598     return retCode;
1599 }
1600 
EncodeEditScenePicture()1601 uint32_t ExtEncoder::EncodeEditScenePicture()
1602 {
1603     bool cond = !picture_;
1604     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DATA_ABNORMAL, "picture_ is nullptr");
1605     auto mainPixelMap = picture_->GetMainPixel();
1606     cond = !mainPixelMap || mainPixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1607     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DATA_ABNORMAL,
1608         "MainPixelMap is nullptr or mainPixelMap is not DMA buffer");
1609 
1610     bool sdrIsSRGB = mainPixelMap->GetToSdrColorSpaceIsSRGB();
1611     SkImageInfo baseInfo = GetSkInfo(mainPixelMap.get(), false, false);
1612     sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(mainPixelMap->GetFd()));
1613     cond = !baseSptr;
1614     CHECK_ERROR_RETURN_RET_LOG(cond, IMAGE_RESULT_CREATE_SURFAC_FAILED, "creat main pixels surfaceBuffer error");
1615     uint32_t errorCode = EncodeHeifPicture(baseSptr, baseInfo, sdrIsSRGB);
1616     RecycleResources();
1617     return errorCode;
1618 }
1619 
EncodeHeifPicture(sptr<SurfaceBuffer> & mainSptr,SkImageInfo mainInfo,bool sdrIsSRGB)1620 uint32_t ExtEncoder::EncodeHeifPicture(sptr<SurfaceBuffer>& mainSptr, SkImageInfo mainInfo, bool sdrIsSRGB)
1621 {
1622 #ifdef HEIF_HW_ENCODE_ENABLE
1623     uint32_t error = SUCCESS;
1624     std::vector<ImageItem> inputImgs;
1625     std::vector<MetaItem> inputMetas;
1626     std::vector<ItemRef> refs;
1627     switch (opts_.desiredDynamicRange) {
1628         case EncodeDynamicRange::AUTO:
1629             if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP) &&
1630                 AssembleHeifHdrPicture(mainSptr, sdrIsSRGB, inputImgs) == SUCCESS) {
1631                 AssembleDualHdrRefItem(refs);
1632             } else {
1633                 inputImgs.clear();
1634                 error = AssembleSdrImageItem(mainSptr, mainInfo, inputImgs);
1635             }
1636             break;
1637         case EncodeDynamicRange::SDR:
1638             error = AssembleSdrImageItem(mainSptr, mainInfo, inputImgs);
1639             break;
1640         case EncodeDynamicRange::HDR_VIVID_DUAL:
1641             if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP)) {
1642                 error = AssembleHeifHdrPicture(mainSptr, sdrIsSRGB, inputImgs);
1643                 AssembleDualHdrRefItem(refs);
1644             } else {
1645                 IMAGE_LOGE("Picture don't has GAINMAP pixels");
1646                 error = ERR_IMAGE_ENCODE_FAILED;
1647             }
1648             break;
1649         case EncodeDynamicRange::HDR_VIVID_SINGLE:
1650             IMAGE_LOGE("Heif picture not support HDR_VIVID_SINGLE");
1651             return ERR_IMAGE_ENCODE_FAILED;
1652         default:
1653             return ERR_IMAGE_INVALID_PARAMETER;
1654     }
1655     bool cond = error != SUCCESS;
1656     CHECK_ERROR_RETURN_RET(cond, error);
1657     if (AssembleExifMetaItem(inputMetas)) {
1658         AssembleExifRefItem(refs);
1659     }
1660     error = AssembleHeifAuxiliaryPicture(inputImgs, refs);
1661     cond = error != SUCCESS;
1662     CHECK_ERROR_RETURN_RET(cond, error);
1663     return DoHeifEncode(inputImgs, inputMetas, refs);
1664 #else
1665     return ERR_IMAGE_INVALID_PARAMETER;
1666 #endif
1667 }
1668 
CheckJpegAuxiliaryTagName()1669 void ExtEncoder::CheckJpegAuxiliaryTagName()
1670 {
1671     if (picture_ == nullptr) {
1672         return;
1673     }
1674     auto auxTypes = ImageUtils::GetAllAuxiliaryPictureType();
1675     for (AuxiliaryPictureType auxType : auxTypes) {
1676         auto auxPicture = picture_->GetAuxiliaryPicture(auxType);
1677         if (auxPicture == nullptr) {
1678             continue;
1679         }
1680         AuxiliaryPictureInfo auxInfo = auxPicture->GetAuxiliaryPictureInfo();
1681         auto iter = DEFAULT_AUXILIARY_TAG_MAP.find(auxType);
1682         if (auxInfo.jpegTagName.size() == 0 && iter != DEFAULT_AUXILIARY_TAG_MAP.end()) {
1683             auxInfo.jpegTagName = iter->second;
1684             auxPicture->SetAuxiliaryPictureInfo(auxInfo);
1685         }
1686     }
1687 }
1688 
EncodeJpegPicture(SkWStream & skStream)1689 uint32_t ExtEncoder::EncodeJpegPicture(SkWStream& skStream)
1690 {
1691     uint32_t error = ERR_IMAGE_ENCODE_FAILED;
1692     switch (opts_.desiredDynamicRange) {
1693         case EncodeDynamicRange::AUTO:
1694             error = EncodeJpegPictureDualVivid(skStream);
1695             if (error != SUCCESS) {
1696                 IMAGE_LOGI("%{public}s jpeg picture encode dual vivid failed, try encode sdr", __func__);
1697                 error = EncodeJpegPictureSdr(skStream);
1698             }
1699             break;
1700         case EncodeDynamicRange::SDR:
1701             error = EncodeJpegPictureSdr(skStream);
1702             break;
1703         case EncodeDynamicRange::HDR_VIVID_DUAL:
1704             error = EncodeJpegPictureDualVivid(skStream);
1705             break;
1706         case EncodeDynamicRange::HDR_VIVID_SINGLE:
1707             error = ERR_IMAGE_DECODE_FAILED;
1708             break;
1709         default:
1710             error = ERR_IMAGE_INVALID_PARAMETER;
1711             break;
1712     }
1713     return error;
1714 }
1715 
EncodeJpegPictureDualVividInner(SkWStream & skStream,std::shared_ptr<PixelMap> & mainPixelmap,std::shared_ptr<PixelMap> & gainmapPixelmap)1716 uint32_t ExtEncoder::EncodeJpegPictureDualVividInner(SkWStream& skStream, std::shared_ptr<PixelMap>& mainPixelmap,
1717     std::shared_ptr<PixelMap>& gainmapPixelmap)
1718 {
1719     bool mainIsSRGB = mainPixelmap->GetToSdrColorSpaceIsSRGB();
1720     SkImageInfo baseInfo = GetSkInfo(mainPixelmap.get(), false, mainIsSRGB);
1721     sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(mainPixelmap->GetFd()));
1722     VpeUtils::SetSbMetadataType(baseSptr, CM_IMAGE_HDR_VIVID_DUAL);
1723     VpeUtils::SetSbColorSpaceType(baseSptr, mainIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
1724     pixelmap_ = mainPixelmap.get();
1725     sk_sp<SkData> baseImageData = GetImageEncodeData(baseSptr, baseInfo, opts_.needsPackProperties);
1726 
1727     bool gainmapIsSRGB = gainmapPixelmap->GetToSdrColorSpaceIsSRGB();
1728     SkImageInfo gainmapInfo = GetSkInfo(gainmapPixelmap.get(), true, gainmapIsSRGB);
1729     ImageInfo tempInfo;
1730     gainmapPixelmap->GetImageInfo(tempInfo);
1731     gainmapInfo = gainmapInfo.makeWH(tempInfo.size.width, tempInfo.size.height);
1732     sptr<SurfaceBuffer> gainMapSptr(reinterpret_cast<SurfaceBuffer*>(gainmapPixelmap->GetFd()));
1733     VpeUtils::SetSbMetadataType(gainMapSptr, CM_METADATA_NONE);
1734     VpeUtils::SetSbColorSpaceType(gainMapSptr, gainmapIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
1735     pixelmap_ = gainmapPixelmap.get();
1736     sk_sp<SkData> gainMapImageData = GetImageEncodeData(gainMapSptr, gainmapInfo, false);
1737 
1738     HdrMetadata hdrMetadata = GetHdrMetadata(baseSptr, gainMapSptr);
1739     SkDynamicMemoryWStream hdrStream;
1740     uint32_t error = HdrJpegPackerHelper::SpliceHdrStream(baseImageData, gainMapImageData, hdrStream, hdrMetadata);
1741     IMAGE_LOGD("%{public}s splice hdr stream result is: %{public}u", __func__, error);
1742     if (error == SUCCESS) {
1743         sk_sp<SkData> hdrSkData = hdrStream.detachAsData();
1744         skStream.write(hdrSkData->data(), hdrSkData->size());
1745         EncodeJpegAuxiliaryPictures(skStream);
1746     }
1747     return error;
1748 }
1749 
EncodeJpegPictureDualVivid(SkWStream & skStream)1750 uint32_t ExtEncoder::EncodeJpegPictureDualVivid(SkWStream& skStream)
1751 {
1752     ImageFuncTimer imageFuncTimer("%s enter", __func__);
1753     if (!picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP)) {
1754         IMAGE_LOGE("%{public}s no gainmap in picture", __func__);
1755         return ERR_IMAGE_INVALID_PARAMETER;
1756     }
1757     auto mainPixelmap = picture_->GetMainPixel();
1758     auto gainmapPixelmap = picture_->GetGainmapPixelMap();
1759     bool cond = !mainPixelmap || !gainmapPixelmap;
1760     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1761         "%{public}s mainPixelmap or gainmapPixelmap is null", __func__);
1762     AllocatorType mainAllocType = mainPixelmap->GetAllocatorType();
1763     AllocatorType gainmapAllocType = gainmapPixelmap->GetAllocatorType();
1764     cond = mainAllocType != AllocatorType::DMA_ALLOC || gainmapAllocType != AllocatorType::DMA_ALLOC;
1765     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED,
1766         "%{public}s AllocatorType is not DMA, mainAllocType: %{public}d, gainmapAllocType: %{public}d",
1767         __func__, mainAllocType, gainmapAllocType);
1768     return EncodeJpegPictureDualVividInner(skStream, mainPixelmap, gainmapPixelmap);
1769 }
1770 
EncodeJpegPictureSdr(SkWStream & skStream)1771 uint32_t ExtEncoder::EncodeJpegPictureSdr(SkWStream& skStream)
1772 {
1773     ImageFuncTimer imageFuncTimer("%s enter", __func__);
1774     auto mainPixelmap = picture_->GetMainPixel();
1775     bool cond = !mainPixelmap;
1776     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s mainPixelmap is null", __func__);
1777     pixelmap_ = mainPixelmap.get();
1778     uint32_t error = ERR_IMAGE_ENCODE_FAILED;
1779     if (!mainPixelmap->IsHdr()) {
1780         error = EncodeImageByPixelMap(mainPixelmap.get(), opts_.needsPackProperties, skStream);
1781         IMAGE_LOGD("%{public}s encode sdr picture result is: %{public}u", __func__, error);
1782     } else {
1783         cond = mainPixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1784         CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "pixelmap is 10bit, but not dma buffer");
1785         bool mainIsSRGB = mainPixelmap->GetToSdrColorSpaceIsSRGB();
1786         SkImageInfo baseInfo = GetSkInfo(mainPixelmap.get(), false, mainIsSRGB);
1787         sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(mainPixelmap->GetFd()));
1788         VpeUtils::SetSbMetadataType(baseSptr, CM_IMAGE_HDR_VIVID_DUAL);
1789         VpeUtils::SetSbColorSpaceType(baseSptr, mainIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
1790         error = EncodeImageBySurfaceBuffer(baseSptr, baseInfo, opts_.needsPackProperties, skStream);
1791         IMAGE_LOGD("%{public}s encode hdr picture result is: %{public}u", __func__, error);
1792     }
1793     if (error == SUCCESS) {
1794         EncodeJpegAuxiliaryPictures(skStream);
1795     }
1796     return error;
1797 }
1798 
GetMetadataValueInt32(const std::shared_ptr<ImageMetadata> & metadata,const std::string & key,int32_t & outVal)1799 static bool GetMetadataValueInt32(const std::shared_ptr<ImageMetadata>& metadata, const std::string& key,
1800     int32_t& outVal)
1801 {
1802     std::string strVal("");
1803     uint32_t u32Val = 0;
1804     bool cond = metadata == nullptr;
1805     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s: metadata is nullptr!", __func__);
1806     cond = metadata->GetValue(key, strVal) != SUCCESS || !ImageUtils::StrToUint32(strVal, u32Val);
1807     CHECK_ERROR_RETURN_RET_LOG(cond, false,
1808         "%{public}s: get metadata key[%{public}s]'s value failed!", __func__, key.c_str());
1809     outVal = static_cast<int32_t>(u32Val);
1810     return true;
1811 }
1812 
CheckFragmentMetadata(Picture * picture,Media::Rect & outData)1813 static bool CheckFragmentMetadata(Picture* picture, Media::Rect& outData)
1814 {
1815     bool cond = !picture || !picture->GetMainPixel() ||
1816         !picture->HasAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP);
1817     CHECK_ERROR_RETURN_RET_LOG(cond, false,
1818         "%{public}s: picture or mainPixelMap or fragment picture does not exist!", __func__);
1819     int32_t mainW = picture->GetMainPixel()->GetWidth();
1820     int32_t mainH = picture->GetMainPixel()->GetHeight();
1821 
1822     auto fragmentPicture = picture->GetAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP);
1823     auto fragmentMetadata = fragmentPicture->GetMetadata(MetadataType::FRAGMENT);
1824     cond = fragmentMetadata == nullptr;
1825     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s: fragmentMetadata is nullptr!", __func__);
1826     cond = !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_X, outData.left) ||
1827         !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_Y, outData.top) ||
1828         !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_WIDTH, outData.width) ||
1829         !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_HEIGHT, outData.height);
1830     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s: GetMetadataValueInt32 failed!", __func__);
1831     if (!ImageUtils::IsInRange(outData.left, 0, mainW) || !ImageUtils::IsInRange(outData.top, 0, mainH) ||
1832         !ImageUtils::IsInRange(outData.width, 0, mainW) || !ImageUtils::IsInRange(outData.height, 0, mainH) ||
1833         !ImageUtils::IsInRange(outData.left + outData.width, 0, mainW) ||
1834         !ImageUtils::IsInRange(outData.top + outData.height, 0, mainH)) {
1835         IMAGE_LOGW("%{public}s: Fragment Rect is not in main Rect!", __func__);
1836         return false;
1837     }
1838     return true;
1839 }
1840 
EncodeJpegAuxiliaryPictures(SkWStream & skStream)1841 void ExtEncoder::EncodeJpegAuxiliaryPictures(SkWStream& skStream)
1842 {
1843     ImageFuncTimer imageFuncTimer("%s enter", __func__);
1844     auto auxTypes = ImageUtils::GetAllAuxiliaryPictureType();
1845     for (AuxiliaryPictureType auxType : auxTypes) {
1846         auto auxPicture = picture_->GetAuxiliaryPicture(auxType);
1847         // Gainmap has been encoded before
1848         if (auxPicture == nullptr || auxType == AuxiliaryPictureType::GAINMAP) {
1849             continue;
1850         }
1851         IMAGE_LOGI("%{public}s try to encode auxiliary picture type: %{public}d", __func__, auxType);
1852         uint32_t error = ERR_IMAGE_ENCODE_FAILED;
1853         size_t writtenSize = skStream.bytesWritten();
1854         if (ImageUtils::IsAuxiliaryPictureEncoded(auxType)) {
1855             error = WriteJpegCodedData(auxPicture, skStream);
1856         } else {
1857             error = WriteJpegUncodedData(auxPicture, skStream);
1858         }
1859         if (error != SUCCESS) {
1860             IMAGE_LOGE("%{public}s encode auxiliary picture type [%{public}d] failed, error: %{public}u",
1861                 __func__, auxType, error);
1862         } else {
1863             uint32_t currentDataSize = static_cast<uint32_t>(skStream.bytesWritten() - writtenSize);
1864             WriteJpegAuxiliarySizeAndTag(currentDataSize, auxPicture, skStream);
1865         }
1866     }
1867 }
1868 
WriteJpegCodedData(std::shared_ptr<AuxiliaryPicture> & auxPicture,SkWStream & skStream)1869 uint32_t ExtEncoder::WriteJpegCodedData(std::shared_ptr<AuxiliaryPicture>& auxPicture, SkWStream& skStream)
1870 {
1871     auto pixelMap = auxPicture->GetContentPixel();
1872     bool cond = pixelMap == nullptr;
1873     CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DATA_ABNORMAL);
1874     pixelmap_ = pixelMap.get();
1875     sk_sp<SkData> skData = nullptr;
1876     if (pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC || pixelMap->GetFd() == nullptr) {
1877         SkDynamicMemoryWStream nonDMAStream;
1878         uint32_t error = EncodeImageByPixelMap(pixelmap_, false, nonDMAStream);
1879         IMAGE_LOGD("%{public}s EncodeImageByPixelMap result: %{public}u", __func__, error);
1880         skData = nonDMAStream.detachAsData();
1881     } else {
1882         sptr<SurfaceBuffer> auxSptr(reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()));
1883         bool isSRGB = pixelMap->GetToSdrColorSpaceIsSRGB();
1884         SkImageInfo skInfo = GetSkInfo(pixelmap_, false, isSRGB);
1885         skData = GetImageEncodeData(auxSptr, skInfo, false);
1886     }
1887     cond = skData == nullptr;
1888     CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_ENCODE_FAILED);
1889     cond = auxPicture->GetType() == AuxiliaryPictureType::FRAGMENT_MAP;
1890     CHECK_ERROR_RETURN_RET(cond, SpliceFragmentStream(skStream, skData));
1891     skStream.write(skData->data(), skData->size());
1892     return SUCCESS;
1893 }
1894 
SpliceFragmentStream(SkWStream & skStream,sk_sp<SkData> & skData)1895 uint32_t ExtEncoder::SpliceFragmentStream(SkWStream& skStream, sk_sp<SkData>& skData)
1896 {
1897     Media::Rect fragmentMetadata;
1898     bool cond = !CheckFragmentMetadata(picture_, fragmentMetadata);
1899     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_PROPERTY_NOT_EXIST,
1900         "%{public}s: CheckFragmentMetadata failed!", __func__);
1901     const uint8_t* dataBytes = reinterpret_cast<const uint8_t*>(skData->data());
1902     // write JPEG SOI(0xFFD8)
1903     skStream.write(dataBytes, JPEG_MARKER_TAG_SIZE);
1904     std::vector<uint8_t> packedFragmentMetadata = JpegMpfPacker::PackFragmentMetadata(fragmentMetadata);
1905     // write fragment metadata
1906     skStream.write(packedFragmentMetadata.data(), packedFragmentMetadata.size());
1907     // write fragment auxiliary image data
1908     skStream.write(dataBytes + JPEG_MARKER_TAG_SIZE, skData->size() - JPEG_MARKER_TAG_SIZE);
1909     return SUCCESS;
1910 }
1911 
WriteJpegUncodedData(std::shared_ptr<AuxiliaryPicture> & auxPicture,SkWStream & skStream)1912 uint32_t ExtEncoder::WriteJpegUncodedData(std::shared_ptr<AuxiliaryPicture>& auxPicture, SkWStream& skStream)
1913 {
1914     auto pixelMap = auxPicture->GetContentPixel();
1915     bool cond = pixelMap == nullptr;
1916     CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DATA_ABNORMAL);
1917     void* bytes = nullptr;
1918     uint32_t size = 0;
1919     Size imageSize;
1920     if (pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC || pixelMap->GetFd() == nullptr) {
1921         bytes = pixelMap->GetWritablePixels();
1922         size = pixelMap->GetCapacity();
1923         imageSize.width = pixelMap->GetWidth();
1924         imageSize.height = pixelMap->GetHeight();
1925     } else {
1926         auto surfaceBuffer = reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
1927         bytes = surfaceBuffer->GetVirAddr();
1928         size = surfaceBuffer->GetSize();
1929         imageSize.width = surfaceBuffer->GetWidth();
1930         imageSize.height = surfaceBuffer->GetHeight();
1931     }
1932     uint32_t writeSize = imageSize.width * imageSize.height;
1933     AuxiliaryPictureInfo auxInfo = auxPicture->GetAuxiliaryPictureInfo();
1934     if (auxInfo.auxiliaryPictureType == AuxiliaryPictureType::DEPTH_MAP) {
1935         writeSize *= DEPTH_MAP_BYTES;
1936     } else if (auxInfo.auxiliaryPictureType == AuxiliaryPictureType::LINEAR_MAP) {
1937         writeSize *= LINEAR_MAP_BYTES;
1938     }
1939     IMAGE_LOGD("%{public}s auxType: %{public}d, width: %{public}d, height: %{public}d, buffer size: %{public}u,"
1940         " write size: %{public}u", __func__, auxInfo.auxiliaryPictureType, imageSize.width, imageSize.height,
1941         size, writeSize);
1942     skStream.write(bytes, std::min(size, writeSize));
1943     return SUCCESS;
1944 }
1945 
WriteJpegAuxiliarySizeAndTag(uint32_t size,std::shared_ptr<AuxiliaryPicture> & auxPicture,SkWStream & skStream)1946 void ExtEncoder::WriteJpegAuxiliarySizeAndTag(uint32_t size, std::shared_ptr<AuxiliaryPicture>& auxPicture,
1947     SkWStream& skStream)
1948 {
1949     // Write auxiliary image size(little endian)
1950     std::vector<uint8_t> auxSize = JpegMpfPacker::PackDataSize(size, false);
1951     skStream.write(auxSize.data(), auxSize.size());
1952 
1953     // Write auxiliary tag name
1954     AuxiliaryPictureInfo auxInfo = auxPicture->GetAuxiliaryPictureInfo();
1955     std::vector<uint8_t> tagName = JpegMpfPacker::PackAuxiliaryTagName(auxInfo.jpegTagName);
1956     skStream.write(tagName.data(), tagName.size());
1957 }
1958 #endif
1959 
1960 #ifdef HEIF_HW_ENCODE_ENABLE
GetBufferSize(size_t contentSize)1961 static size_t GetBufferSize(size_t contentSize)
1962 {
1963     return sizeof(PropertyType) + sizeof(int) + contentSize;
1964 }
1965 
1966 // format: enum + int buffersize + buffer
FillImagePropertyItem(const std::shared_ptr<AbsMemory> & mem,const size_t offset,PropertyType type,const void * payloadData,size_t payloadSize)1967 static bool FillImagePropertyItem(const std::shared_ptr<AbsMemory> &mem, const size_t offset,
1968     PropertyType type, const void* payloadData, size_t payloadSize)
1969 {
1970     uint8_t* memData = reinterpret_cast<uint8_t*>(mem->data.data);
1971     size_t memSize = mem->data.size;
1972     IMAGE_LOGD("FileImagePropertyItem memSize is %{public}ld, payloadSize is %{public}ld", memSize, payloadSize);
1973     IMAGE_LOGD("FileImagePropertyItem sizeof(type) is %{public}ld, sizeof(payloadSize) %{public}ld",
1974         sizeof(type), sizeof(payloadSize));
1975     bool cond = payloadSize > INT32_MAX;
1976     CHECK_INFO_RETURN_RET_LOG(cond, false, "payloadSize is over INT32_MAX");
1977     int payloadIntSize = static_cast<int>(payloadSize);
1978     size_t typeSize = sizeof(type);
1979     size_t intSize = sizeof(int);
1980     bool res = (memcpy_s(memData + offset, memSize - offset, &type, typeSize) == EOK) &&
1981         (memcpy_s(memData + offset + typeSize, memSize - offset - typeSize, &payloadIntSize, intSize) == EOK) &&
1982         (memcpy_s(memData + offset + typeSize + intSize, memSize - offset - typeSize - intSize,
1983         payloadData, payloadSize) == EOK);
1984     return res;
1985 }
1986 
AllocateNewSharedMem(size_t memorySize,std::string tag)1987 std::shared_ptr<AbsMemory> ExtEncoder::AllocateNewSharedMem(size_t memorySize, std::string tag)
1988 {
1989     MemoryData memoryData;
1990     memoryData.size = memorySize;
1991     memoryData.tag = tag.empty() ? DEFAULT_ASHMEM_TAG.c_str() : tag.c_str();
1992     std::unique_ptr<AbsMemory> memory =
1993         MemoryManager::CreateMemory(AllocatorType::SHARE_MEM_ALLOC, memoryData);
1994     std::shared_ptr<AbsMemory> res = std::move(memory);
1995     return res;
1996 }
1997 
GetStaticMetadata(HdrMetadata & metadata,MasteringDisplayColourVolume & color,ContentLightLevel & light)1998 bool ExtEncoder::GetStaticMetadata(HdrMetadata& metadata, MasteringDisplayColourVolume& color, ContentLightLevel& light)
1999 {
2000     HdrStaticMetadata staticMetadata;
2001     size_t staticMetadataSize = sizeof(HdrStaticMetadata);
2002     bool cond = metadata.staticMetadata.size() < staticMetadataSize;
2003     CHECK_INFO_RETURN_RET_LOG(cond, false, "GetStaticMetadata failed");
2004     cond = memcpy_s(&staticMetadata, staticMetadataSize,
2005         metadata.staticMetadata.data(), metadata.staticMetadata.size()) != EOK;
2006     CHECK_INFO_RETURN_RET_LOG(cond, false, "GetStaticMetadata failed, memcpy_s failed");
2007     color.displayPrimariesRX =
2008         (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryRed.x);
2009     color.displayPrimariesRY =
2010         (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryRed.y);
2011     color.displayPrimariesGX =
2012         (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryGreen.x);
2013     color.displayPrimariesGY =
2014         (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryGreen.y);
2015     color.displayPrimariesBX =
2016         (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryBlue.x);
2017     color.displayPrimariesBY =
2018         (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryBlue.y);
2019     color.whitePointX = (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.whitePoint.x);
2020     color.whitePointY = (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.whitePoint.y);
2021     color.maxDisplayMasteringLuminance = (uint32_t)staticMetadata.smpte2086.maxLuminance;
2022     color.minDisplayMasteringLuminance = (uint32_t)(STATIC_METADATA_LUM_SCALE * staticMetadata.smpte2086.minLuminance);
2023     light.maxContentLightLevel = (uint16_t)staticMetadata.cta861.maxContentLightLevel;
2024     light.maxPicAverageLightLevel = (uint16_t)staticMetadata.cta861.maxFrameAverageLightLevel;
2025     return true;
2026 }
2027 
GetToneMapChannel(ISOMetadata & metadata,ToneMapChannel & channel,uint8_t index)2028 bool ExtEncoder::GetToneMapChannel(ISOMetadata& metadata, ToneMapChannel& channel, uint8_t index)
2029 {
2030     bool cond = index > GAINMAP_CHANNEL_MULTI - 1;
2031     CHECK_ERROR_RETURN_RET_LOG(cond, false, "GetToneMapChannel index:[%{public}d] unsupported", index);
2032     channel.gainMapMin.numerator = DEFAULT_DENOMINATOR * metadata.enhanceClippedThreholdMinGainmap[index];
2033     channel.gainMapMin.denominator = DEFAULT_DENOMINATOR;
2034     channel.gainMapMax.numerator = DEFAULT_DENOMINATOR * metadata.enhanceClippedThreholdMaxGainmap[index];
2035     channel.gainMapMax.denominator = DEFAULT_DENOMINATOR;
2036     if (metadata.enhanceMappingGamma[index] > 0.0f) {
2037         channel.gamma.numerator = DEFAULT_DENOMINATOR * metadata.enhanceMappingGamma[index];
2038     } else {
2039         channel.gamma.numerator = 0;
2040     }
2041     channel.gamma.denominator = DEFAULT_DENOMINATOR;
2042     channel.baseOffset.numerator = DEFAULT_DENOMINATOR * metadata.enhanceMappingBaselineOffset[index];
2043     channel.baseOffset.denominator = DEFAULT_DENOMINATOR;
2044     channel.alternateOffset.numerator = DEFAULT_DENOMINATOR * metadata.enhanceMappingAlternateOffset[index];
2045     channel.alternateOffset.denominator = DEFAULT_DENOMINATOR;
2046     IMAGE_LOGD("GetToneMapChannel [%{public}d],gainmapMin:%{public}f, gainmapMax:%{public}f,"
2047         "gamma:%{public}f,baseOffset:%{public}f, alternateOffset:%{public}f", index,
2048         metadata.enhanceClippedThreholdMinGainmap[index], metadata.enhanceClippedThreholdMaxGainmap[index],
2049         metadata.enhanceMappingGamma[index],
2050         metadata.enhanceMappingBaselineOffset[index], metadata.enhanceMappingAlternateOffset[index]);
2051     return true;
2052 }
2053 
GetToneMapMetadata(HdrMetadata & metadata,ToneMapMetadata & toneMapMetadata)2054 bool ExtEncoder::GetToneMapMetadata(HdrMetadata& metadata, ToneMapMetadata& toneMapMetadata)
2055 {
2056     ISOMetadata isoMeta = metadata.extendMeta.metaISO;
2057     toneMapMetadata.useBaseColorSpace = (isoMeta.useBaseColorFlag == 1) ? true : false;
2058     toneMapMetadata.channelCnt = (isoMeta.gainmapChannelNum == 0) ? GAINMAP_CHANNEL_SINGLE : GAINMAP_CHANNEL_MULTI;
2059     toneMapMetadata.baseHdrHeadroom.denominator = DEFAULT_DENOMINATOR;
2060     if (isoMeta.baseHeadroom > 0.0f) {
2061         toneMapMetadata.baseHdrHeadroom.numerator = (uint32_t)(isoMeta.baseHeadroom * DEFAULT_DENOMINATOR);
2062     } else {
2063         toneMapMetadata.baseHdrHeadroom.numerator = 0;
2064     }
2065     toneMapMetadata.alternateHdrHeadroom.denominator = DEFAULT_DENOMINATOR;
2066     if (isoMeta.alternateHeadroom > 0.0f) {
2067         toneMapMetadata.alternateHdrHeadroom.numerator = (uint32_t)(isoMeta.alternateHeadroom * DEFAULT_DENOMINATOR);
2068     } else {
2069         toneMapMetadata.alternateHdrHeadroom.numerator = 0;
2070     }
2071     GetToneMapChannel(isoMeta, toneMapMetadata.channels1, INDEX_ZERO);
2072     if (toneMapMetadata.channelCnt == GAINMAP_CHANNEL_MULTI) {
2073         GetToneMapChannel(isoMeta, toneMapMetadata.channels2, INDEX_ONE);
2074         GetToneMapChannel(isoMeta, toneMapMetadata.channels3, INDEX_TWO);
2075     }
2076     IMAGE_LOGD("GetToneMapMetadata useBaseColorSpace:%{public}d, gainmapChannelNum:%{public}d,"
2077         "baseHeadroom:%{public}f,alternateHeadroom:%{public}f", isoMeta.useBaseColorFlag, isoMeta.gainmapChannelNum,
2078         isoMeta.baseHeadroom, isoMeta.alternateHeadroom);
2079     return true;
2080 }
2081 
GetColourInfo(ColorManager::ColorSpaceName color,ColourInfo & info)2082 void ExtEncoder::GetColourInfo(ColorManager::ColorSpaceName color, ColourInfo& info)
2083 {
2084     uint8_t fullRangeFlag;
2085     ColorUtils::ColorSpaceGetCicp(color, info.colourPrimaries, info.transferCharacteristics, info.matrixCoefficients,
2086         fullRangeFlag);
2087     // 1 : full range ; 0 : limit range.
2088     info.fullRangeFlag = (fullRangeFlag == 1);
2089 }
2090 
AssembleIT35SharedBuffer(HdrMetadata metadata,SharedBuffer & outBuffer)2091 bool ExtEncoder::AssembleIT35SharedBuffer(HdrMetadata metadata, SharedBuffer& outBuffer)
2092 {
2093     std::vector<uint8_t> it35Info;
2094     bool cond = !HdrHeifPackerHelper::PackIT35Info(metadata, it35Info);
2095     CHECK_ERROR_RETURN_RET_LOG(cond, false, "get it35 info failed");
2096     std::shared_ptr<AbsMemory> propertyAshmem =
2097         AllocateNewSharedMem(GetBufferSize(it35Info.size()), IT35_ASHMEM_TAG);
2098     cond = propertyAshmem == nullptr;
2099     CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleIT35SharedBuffer it35 alloc failed");
2100     tmpMemoryList_.push_back(propertyAshmem);
2101     cond = !FillImagePropertyItem(propertyAshmem, 0, PropertyType::IT35_INFO, it35Info.data(), it35Info.size());
2102     CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleIT35SharedBuffer fill failed");
2103     outBuffer.fd = *static_cast<int *>(propertyAshmem->extend.data);
2104     outBuffer.capacity = propertyAshmem->data.size;
2105     outBuffer.filledLen = propertyAshmem->data.size;
2106     return true;
2107 }
2108 
AssembleICCImageProperty(sk_sp<SkData> & iccProfile,SharedBuffer & outBuffer)2109 bool ExtEncoder::AssembleICCImageProperty(sk_sp<SkData>& iccProfile, SharedBuffer& outBuffer)
2110 {
2111     bool cond = iccProfile == nullptr || iccProfile->size() == 0;
2112     CHECK_INFO_RETURN_RET_LOG(cond, false, "AssembleICCImageProperty iccprofile is nullptr");
2113     std::shared_ptr<AbsMemory> propertyAshmem =
2114         AllocateNewSharedMem(GetBufferSize(iccProfile->size()), ICC_ASHMEM_TAG);
2115     cond = propertyAshmem == nullptr;
2116     CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleICCImageProperty alloc failed");
2117     tmpMemoryList_.push_back(propertyAshmem);
2118     bool fillRes = FillImagePropertyItem(propertyAshmem, 0, PropertyType::ICC_PROFILE,
2119         iccProfile->data(), iccProfile->size());
2120     if (fillRes) {
2121         outBuffer.fd = *static_cast<int *>(propertyAshmem->extend.data);
2122         outBuffer.capacity = propertyAshmem->data.size;
2123         outBuffer.filledLen = propertyAshmem->data.size;
2124     }
2125     return fillRes;
2126 }
2127 
FillNclxColorProperty(std::shared_ptr<ImageItem> & item,size_t & offset,ColourInfo & colorInfo)2128 bool ExtEncoder::FillNclxColorProperty(std::shared_ptr<ImageItem>& item, size_t& offset, ColourInfo& colorInfo)
2129 {
2130     ColorType colorType = ColorType::NCLX;
2131     bool cond = !FillLitePropertyItem(item->liteProperties, offset,
2132         PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
2133     CHECK_ERROR_RETURN_RET_LOG(cond, false, "Fill colorType failed");
2134     cond = !FillLitePropertyItem(item->liteProperties, offset,
2135         PropertyType::COLOR_INFO, &colorInfo, sizeof(ColourInfo));
2136     CHECK_INFO_RETURN_RET_LOG(cond, false, "Fill colorInfo failed");
2137     return true;
2138 }
2139 
AssembleOutputSharedBuffer(SharedBuffer & outBuffer,std::shared_ptr<AbsMemory> & outMem)2140 bool ExtEncoder::AssembleOutputSharedBuffer(SharedBuffer& outBuffer, std::shared_ptr<AbsMemory>& outMem)
2141 {
2142     bool cond = output_ == nullptr;
2143     CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleOutputSharedBuffer output_ is nullptr");
2144     OutputStreamType outType = output_->GetType();
2145     size_t outputCapacity = DEFAULT_OUTPUT_SIZE;
2146     if (outType != OutputStreamType::FILE_PACKER) {
2147         output_->GetCapicity(outputCapacity);
2148     }
2149     std::shared_ptr<AbsMemory> mem = AllocateNewSharedMem(outputCapacity, OUTPUT_ASHMEM_TAG);
2150     cond = mem == nullptr;
2151     CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleOutputSharedBuffer alloc out sharemem failed");
2152     outMem = mem;
2153     tmpMemoryList_.push_back(mem);
2154     if (mem->extend.data != nullptr) {
2155         outBuffer.fd = *static_cast<int *>(mem->extend.data);
2156     }
2157     outBuffer.capacity = outputCapacity;
2158     return true;
2159 }
2160 
AssembleDualHdrRefItem(std::vector<ItemRef> & refs)2161 void ExtEncoder::AssembleDualHdrRefItem(std::vector<ItemRef>& refs)
2162 {
2163     auto item = std::make_shared<ItemRef>();
2164     item->type = ReferenceType::DIMG;
2165     item->from = TMAP_IMAGE_ITEM_ID;
2166     item->to.resize(INDEX_TWO);
2167     item->to[INDEX_ZERO] = PRIMARY_IMAGE_ITEM_ID;
2168     item->to[INDEX_ONE] = GAINMAP_IMAGE_ITEM_ID;
2169     refs.push_back(*item);
2170 }
2171 
DoHeifEncode(std::vector<ImageItem> & inputImgs,std::vector<MetaItem> & inputMetas,std::vector<ItemRef> & refs)2172 uint32_t ExtEncoder::DoHeifEncode(std::vector<ImageItem>& inputImgs, std::vector<MetaItem>& inputMetas,
2173     std::vector<ItemRef>& refs)
2174 {
2175     SharedBuffer outputBuffer {};
2176     std::shared_ptr<AbsMemory> outputAshmem;
2177     bool tempRes = AssembleOutputSharedBuffer(outputBuffer, outputAshmem);
2178     bool cond = !tempRes;
2179     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
2180         "ExtEncoder::DoHeifEncode alloc sharedbuffer failed");
2181 
2182     sptr<ICodecImage> codec = GetCodecManager();
2183     CHECK_ERROR_RETURN_RET(codec == nullptr, ERR_IMAGE_ENCODE_FAILED);
2184     uint32_t outSize = DEFAULT_OUTPUT_SIZE;
2185     int32_t encodeRes = codec->DoHeifEncode(inputImgs, inputMetas, refs, outputBuffer, outSize);
2186     cond = encodeRes != HDF_SUCCESS;
2187     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "ExtEncoder::DoHeifEncode DoHeifEncode failed");
2188     IMAGE_LOGI("ExtEncoder::DoHeifEncode output type is %{public}d", output_->GetType());
2189     bool writeRes = output_->Write(reinterpret_cast<uint8_t *>(outputAshmem->data.data), outSize);
2190     cond = !writeRes;
2191     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "ExtEncoder::DoHeifEncode Write failed");
2192     return SUCCESS;
2193 }
2194 
AssembleTmapImageItem(ColorManager::ColorSpaceName color,HdrMetadata metadata,const PlEncodeOptions & opts)2195 std::shared_ptr<ImageItem> ExtEncoder::AssembleTmapImageItem(ColorManager::ColorSpaceName color,
2196     HdrMetadata metadata, const PlEncodeOptions &opts)
2197 {
2198     auto item = std::make_shared<ImageItem>();
2199     item->id = TMAP_IMAGE_ITEM_ID;
2200     item->itemName = "Tone-mapped representation";
2201     item->isPrimary = false;
2202     item->isHidden = false;
2203     item->compressType = COMPRESS_TYPE_TMAP;
2204     item->quality = opts.quality;
2205     item->sharedProperties.fd = -1;
2206     item->pixelSharedBuffer.fd = -1;
2207     ColourInfo colorInfo;
2208     GetColourInfo(color, colorInfo);
2209     ContentLightLevel light;
2210     MasteringDisplayColourVolume colour;
2211     bool hasLight = GetStaticMetadata(metadata, colour, light);
2212     uint32_t propertiesSize = 0;
2213     propertiesSize +=
2214         (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType) + sizeof(PropertyType::COLOR_INFO) + sizeof(ColourInfo));
2215     if (hasLight) {
2216         propertiesSize += (sizeof(PropertyType::CONTENT_LIGHT_LEVEL) + sizeof(ContentLightLevel));
2217     }
2218     ToneMapMetadata toneMap;
2219     bool hasToneMap = GetToneMapMetadata(metadata, toneMap);
2220     if (hasToneMap) {
2221         propertiesSize += (sizeof(PropertyType::TONE_MAP_METADATA) + sizeof(ToneMapMetadata));
2222     }
2223     item->liteProperties.resize(propertiesSize);
2224     size_t offset = 0;
2225     if (!FillNclxColorProperty(item, offset, colorInfo)) {
2226         return nullptr;
2227     }
2228     bool cond = hasLight && (!FillLitePropertyItem(item->liteProperties, offset,
2229         PropertyType::CONTENT_LIGHT_LEVEL, &colour, sizeof(ContentLightLevel)));
2230     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssembleTmapImageItem fill CONTENT_LIGHT_LEVEL failed");
2231     cond = hasToneMap && (!FillLitePropertyItem(item->liteProperties, offset,
2232         PropertyType::TONE_MAP_METADATA, &toneMap, sizeof(ToneMapMetadata)));
2233     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssembleTmapImageItem fill toneMap failed");
2234     cond = !AssembleIT35SharedBuffer(metadata, item->sharedProperties);
2235     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssembleTmapImageItem fill it35 failed");
2236     return item;
2237 }
2238 
2239 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
AssemblePrimaryImageItem(sptr<SurfaceBuffer> & surfaceBuffer,const PlEncodeOptions & opts)2240 std::shared_ptr<ImageItem> ExtEncoder::AssemblePrimaryImageItem(sptr<SurfaceBuffer>& surfaceBuffer,
2241     const PlEncodeOptions &opts)
2242 {
2243     bool cond = pixelmap_ == nullptr || surfaceBuffer == nullptr;
2244     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssemblePrimaryImageItem surfaceBuffer is nullptr");
2245     auto item = std::make_shared<ImageItem>();
2246     item->id = PRIMARY_IMAGE_ITEM_ID;
2247     item->pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
2248     item->isPrimary = true;
2249     item->isHidden = false;
2250     item->compressType = COMPRESS_TYPE_HEVC;
2251     item->quality = opts.quality;
2252     item->sharedProperties.fd = -1;
2253     item->pixelSharedBuffer.fd = -1;
2254     sk_sp<SkData> iccProfile = icc_from_color_space(ToSkInfo(pixelmap_));
2255     bool tempRes = AssembleICCImageProperty(iccProfile, item->sharedProperties);
2256     CHECK_ERROR_RETURN_RET(!tempRes, nullptr);
2257     uint32_t litePropertiesSize = 0;
2258     litePropertiesSize += (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
2259     item->liteProperties.resize(litePropertiesSize);
2260     size_t offset = 0;
2261     ColorType colorType = ColorType::RICC;
2262     cond = !FillLitePropertyItem(item->liteProperties, offset,
2263         PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
2264     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssemblePrimaryImageItem Fill color type failed");
2265     return item;
2266 }
2267 #endif
2268 
AssembleExifRefItem(std::vector<ItemRef> & refs)2269 void ExtEncoder::AssembleExifRefItem(std::vector<ItemRef>& refs)
2270 {
2271     auto item = std::make_shared<ItemRef>();
2272     item->type = ReferenceType::CDSC;
2273     item->from = EXIF_META_ITEM_ID;
2274     item->to.resize(INDEX_ONE);
2275     item->to[INDEX_ZERO] = PRIMARY_IMAGE_ITEM_ID;
2276     refs.push_back(*item);
2277 }
2278 
FreeExifBlob(uint8_t ** exifBlob)2279 void inline FreeExifBlob(uint8_t** exifBlob)
2280 {
2281     if (exifBlob != nullptr && *exifBlob != nullptr) {
2282         free(*exifBlob);
2283         *exifBlob = nullptr;
2284     }
2285 }
2286 
AssembleExifMetaItem(std::vector<MetaItem> & metaItems)2287 bool ExtEncoder::AssembleExifMetaItem(std::vector<MetaItem>& metaItems)
2288 {
2289     if (!opts_.needsPackProperties) {
2290         IMAGE_LOGD("no need encode exif");
2291         return false;
2292     }
2293     ExifData* exifData = nullptr;
2294     if (picture_ != nullptr && picture_->GetExifMetadata() != nullptr &&
2295         picture_->GetExifMetadata()->GetExifData() != nullptr) {
2296         exifData = picture_->GetExifMetadata()->GetExifData();
2297     } else if (pixelmap_ != nullptr && pixelmap_->GetExifMetadata() != nullptr &&
2298         pixelmap_->GetExifMetadata()->GetExifData() != nullptr) {
2299         exifData = pixelmap_->GetExifMetadata()->GetExifData();
2300     } else {
2301         IMAGE_LOGD("no exif");
2302         return false;
2303     }
2304     uint8_t* exifBlob = nullptr;
2305     uint32_t exifSize = 0;
2306     TiffParser::Encode(&exifBlob, exifSize, exifData);
2307     if (exifBlob == nullptr) {
2308         IMAGE_LOGE("Encode exif data failed");
2309         return false;
2310     }
2311     auto item = std::make_shared<MetaItem>();
2312     item->id = EXIF_META_ITEM_ID;
2313     item->itemName = "exif";
2314     item->data.fd = -1;
2315     std::shared_ptr<AbsMemory> propertyAshmem = AllocateNewSharedMem(exifSize + EXIF_PRE_SIZE, EXIF_ASHMEM_TAG);
2316     if (propertyAshmem == nullptr) {
2317         FreeExifBlob(&exifBlob);
2318         IMAGE_LOGE("AssembleExifMetaItem alloc propertyAshmem failed");
2319         return false;
2320     }
2321     tmpMemoryList_.push_back(propertyAshmem);
2322     uint8_t* memData = reinterpret_cast<uint8_t*>(propertyAshmem->data.data);
2323     size_t memSize = propertyAshmem->data.size;
2324     bool fillRes = (memcpy_s(memData, memSize, EXIF_PRE_TAG, EXIF_PRE_SIZE) == EOK) &&
2325         (memcpy_s(memData + EXIF_PRE_SIZE, memSize - EXIF_PRE_SIZE, exifBlob, exifSize) == EOK);
2326     if (fillRes) {
2327         item->data.fd = *static_cast<int *>(propertyAshmem->extend.data);
2328         item->data.capacity = propertyAshmem->data.size;
2329         item->data.filledLen = propertyAshmem->data.size;
2330         metaItems.push_back(*item);
2331     }
2332     FreeExifBlob(&exifBlob);
2333     return fillRes;
2334 }
2335 
FillPixelSharedBuffer(sptr<SurfaceBuffer> sbBuffer,uint32_t capacity,SharedBuffer & outBuffer)2336 bool ExtEncoder::FillPixelSharedBuffer(sptr<SurfaceBuffer> sbBuffer, uint32_t capacity, SharedBuffer& outBuffer)
2337 {
2338     bool cond = sbBuffer == nullptr || capacity == 0;
2339     CHECK_INFO_RETURN_RET_LOG(cond, false, "%{public}s iccprofile is nullptr", __func__);
2340     std::shared_ptr<AbsMemory> sharedMem = AllocateNewSharedMem(capacity, IMAGE_DATA_TAG);
2341     cond = sharedMem == nullptr;
2342     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s alloc failed", __func__);
2343     tmpMemoryList_.push_back(sharedMem);
2344     uint8_t* memData = reinterpret_cast<uint8_t*>(sharedMem->data.data);
2345     size_t memSize = sharedMem->data.size;
2346     cond = capacity > memSize;
2347     CHECK_ERROR_RETURN_RET_LOG(cond, false,
2348         "%{public}s shared capacity[%{public}d] over memSize[%{public}ld]", __func__, capacity, memSize);
2349     cond = sharedMem->extend.data == nullptr;
2350     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s sharedMem's extend data is nullptr", __func__);
2351     if (memcpy_s(memData, memSize, sbBuffer->GetVirAddr(), capacity) == EOK) {
2352         outBuffer.fd = *static_cast<int *>(sharedMem->extend.data);
2353         outBuffer.capacity = memSize;
2354         outBuffer.filledLen = memSize;
2355     } else {
2356         IMAGE_LOGE("%{public}s memcpy failed", __func__);
2357         return false;
2358     }
2359     return true;
2360 }
2361 
AssembleAuxiliaryRefItem(AuxiliaryPictureType type,std::vector<ItemRef> & refs)2362 void ExtEncoder::AssembleAuxiliaryRefItem(AuxiliaryPictureType type, std::vector<ItemRef>& refs)
2363 {
2364     auto item = std::make_shared<ItemRef>();
2365     item->type = ReferenceType::AUXL;
2366     item->to.resize(INDEX_ONE);
2367     item->to[INDEX_ZERO] = PRIMARY_IMAGE_ITEM_ID;
2368     switch (type) {
2369         case AuxiliaryPictureType::DEPTH_MAP:
2370             item->from = DEPTH_MAP_ITEM_ID;
2371             break;
2372         case AuxiliaryPictureType::UNREFOCUS_MAP:
2373             item->from = UNREFOCUS_MAP_ITEM_ID;
2374             break;
2375         case AuxiliaryPictureType::LINEAR_MAP:
2376             item->from = LINEAR_MAP_ITEM_ID;
2377             break;
2378         case AuxiliaryPictureType::FRAGMENT_MAP:
2379             item->from = FRAGMENT_MAP_ITEM_ID;
2380             break;
2381         default:
2382             break;
2383     }
2384     refs.push_back(*item);
2385 }
2386 #endif
2387 } // namespace ImagePlugin
2388 } // namespace OHOS
2389