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