• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "image_source.h"
17 #ifdef EXT_PIXEL
18 #include "pixel_yuv_ext.h"
19 #endif
20 
21 #include <algorithm>
22 #include <cerrno>
23 #include <charconv>
24 #include <chrono>
25 #include <cstring>
26 #include <dlfcn.h>
27 #include <filesystem>
28 #include <mutex>
29 #include <vector>
30 
31 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
32 #include "auxiliary_generator.h"
33 #include "auxiliary_picture.h"
34 #endif
35 
36 #include "buffer_source_stream.h"
37 #if !defined(_WIN32) && !defined(_APPLE)
38 #include "hitrace_meter.h"
39 #include "image_trace.h"
40 #include "image_data_statistics.h"
41 #endif
42 #include "exif_metadata.h"
43 #include "file_source_stream.h"
44 #include "image/abs_image_decoder.h"
45 #include "image/abs_image_format_agent.h"
46 #include "image/image_plugin_type.h"
47 #include "image_format_convert.h"
48 #include "image_log.h"
49 #include "image_packer.h"
50 #include "image_system_properties.h"
51 #include "image_utils.h"
52 #include "incremental_source_stream.h"
53 #include "istream_source_stream.h"
54 #include "jpeg_mpf_parser.h"
55 #include "media_errors.h"
56 #include "memory_manager.h"
57 #include "metadata_accessor.h"
58 #include "metadata_accessor_factory.h"
59 #include "pixel_astc.h"
60 #include "pixel_map.h"
61 #include "pixel_map_utils.h"
62 #include "pixel_yuv.h"
63 #include "plugin_server.h"
64 #include "post_proc.h"
65 #include "securec.h"
66 #include "source_stream.h"
67 #include "image_dfx.h"
68 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
69 #include "include/jpeg_decoder.h"
70 #else
71 #include "surface_buffer.h"
72 #include "native_buffer.h"
73 #include "v1_0/buffer_handle_meta_key_type.h"
74 #include "v1_0/cm_color_space.h"
75 #include "v1_0/hdr_static_metadata.h"
76 #include "vpe_utils.h"
77 #endif
78 #include "include/utils/SkBase64.h"
79 #if defined(NEW_SKIA)
80 #include "include/core/SkData.h"
81 #endif
82 #include "string_ex.h"
83 #include "hdr_type.h"
84 #include "image_mime_type.h"
85 #ifdef IMAGE_QOS_ENABLE
86 #include "qos.h"
87 #endif
88 #ifdef HEIF_HW_DECODE_ENABLE
89 #include "v3_0/codec_types.h"
90 #include "v3_0/icodec_component_manager.h"
91 #endif
92 
93 #undef LOG_DOMAIN
94 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
95 
96 #undef LOG_TAG
97 #define LOG_TAG "ImageSource"
98 
99 namespace OHOS {
100 namespace Media {
101 using namespace std;
102 using namespace ImagePlugin;
103 using namespace MultimediaPlugin;
104 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
105 using namespace HDI::Display::Graphic::Common::V1_0;
106 
107 static const map<PixelFormat, GraphicPixelFormat> SINGLE_HDR_CONVERT_FORMAT_MAP = {
108     { PixelFormat::RGBA_8888, GRAPHIC_PIXEL_FMT_RGBA_8888 },
109     { PixelFormat::NV21, GRAPHIC_PIXEL_FMT_YCRCB_420_SP },
110     { PixelFormat::NV12, GRAPHIC_PIXEL_FMT_YCBCR_420_SP },
111     { PixelFormat::YCRCB_P010, GRAPHIC_PIXEL_FMT_YCRCB_420_SP },
112     { PixelFormat::YCBCR_P010, GRAPHIC_PIXEL_FMT_YCBCR_420_SP },
113 };
114 #endif
115 
116 namespace InnerFormat {
117 const string RAW_FORMAT = "image/x-raw";
118 const string ASTC_FORMAT = "image/astc";
119 const string EXTENDED_FORMAT = "image/x-skia";
120 const string IMAGE_EXTENDED_CODEC = "image/extended";
121 const string SVG_FORMAT = "image/svg+xml";
122 const string RAW_EXTENDED_FORMATS[] = {
123     "image/x-sony-arw",
124     "image/x-canon-cr2",
125     "image/x-adobe-dng",
126     "image/x-nikon-nef",
127     "image/x-nikon-nrw",
128     "image/x-olympus-orf",
129     "image/x-fuji-raf",
130     "image/x-panasonic-rw2",
131     "image/x-pentax-pef",
132     "image/x-samsung-srw",
133 };
134 } // namespace InnerFormat
135 // BASE64 image prefix type data:image/<type>;base64,<data>
136 static const std::string IMAGE_URL_PREFIX = "data:image/";
137 static const std::string BASE64_URL_PREFIX = ";base64,";
138 static const std::string KEY_IMAGE_WIDTH = "ImageWidth";
139 static const std::string KEY_IMAGE_HEIGHT = "ImageLength";
140 static const std::string IMAGE_FORMAT_RAW = "image/raw";
141 static const uint32_t FIRST_FRAME = 0;
142 static const int INT_ZERO = 0;
143 static const size_t SIZE_ZERO = 0;
144 static const uint8_t NUM_0 = 0;
145 static const uint8_t NUM_1 = 1;
146 static const uint8_t NUM_2 = 2;
147 static const uint8_t NUM_3 = 3;
148 static const uint8_t NUM_4 = 4;
149 static const uint8_t NUM_6 = 6;
150 static const uint8_t NUM_8 = 8;
151 static const uint8_t NUM_16 = 16;
152 static const uint8_t NUM_24 = 24;
153 static const uint32_t ASTC_MAGIC_ID = 0x5CA1AB13;
154 static const int ASTC_SIZE = 512 * 512;
155 static const size_t ASTC_HEADER_SIZE = 16;
156 static const uint8_t ASTC_HEADER_BLOCK_X = 4;
157 static const uint8_t ASTC_HEADER_BLOCK_Y = 5;
158 static const uint8_t ASTC_HEADER_DIM_X = 7;
159 static const uint8_t ASTC_HEADER_DIM_Y = 10;
160 static const int IMAGE_HEADER_SIZE = 12;
161 static const uint32_t MAX_SOURCE_SIZE = 300 * 1024 * 1024;
162 constexpr uint8_t ASTC_EXTEND_INFO_TLV_NUM = 1; // curren only one group TLV
163 constexpr uint32_t ASTC_EXTEND_INFO_SIZE_DEFINITION_LENGTH = 4; // 4 bytes to discripte for extend info summary bytes
164 constexpr uint32_t ASTC_EXTEND_INFO_LENGTH_LENGTH = 4; // 4 bytes to discripte the content bytes for every TLV group
165 constexpr uint32_t ASTC_EXTEND_INFO_TLV_SUM_BYTES = 6; // The colorspace TLV length in the astc file stream is 6
166 constexpr int32_t ASTC_MAX_SIZE = 8192;
167 constexpr size_t ASTC_TLV_SIZE = 10; // 10 is tlv size, colorspace size
168 constexpr uint8_t ASTC_OPTION_QUALITY = 85;
169 static constexpr uint32_t SINGLE_FRAME_SIZE = 1;
170 static constexpr uint8_t ISO_USE_BASE_COLOR = 0x01;
171 constexpr int32_t DEFAULT_DMA_SIZE = 512 * 512;
172 constexpr int32_t DMA_ALLOC = 1;
173 constexpr int32_t SHARE_MEMORY_ALLOC = 2;
174 constexpr int32_t AUTO_ALLOC = 0;
175 
176 struct AstcExtendInfo {
177     uint32_t extendBufferSumBytes = 0;
178     uint8_t extendNums = ASTC_EXTEND_INFO_TLV_NUM;
179     uint8_t extendInfoType[ASTC_EXTEND_INFO_TLV_NUM];
180     uint32_t extendInfoLength[ASTC_EXTEND_INFO_TLV_NUM];
181     uint8_t *extendInfoValue[ASTC_EXTEND_INFO_TLV_NUM];
182 };
183 
184 struct StreamInfo {
185     uint8_t* buffer = nullptr;
186     uint32_t size = 0;
187     uint32_t gainmapOffset = 0;
188     bool needDelete = false;    // Require the buffer allocation type to be HEAP ALLOC
189 
GetCurrentAddressOHOS::Media::StreamInfo190     uint8_t* GetCurrentAddress()
191     {
192         return buffer + gainmapOffset;
193     }
194 
GetCurrentSizeOHOS::Media::StreamInfo195     uint32_t GetCurrentSize()
196     {
197         if (size >= gainmapOffset) {
198             return size - gainmapOffset;
199         } else {
200             return 0;
201         }
202     }
203 
~StreamInfoOHOS::Media::StreamInfo204     ~StreamInfo()
205     {
206         if (needDelete && buffer != nullptr) {
207             delete[] buffer;
208             buffer = nullptr;
209         }
210     }
211 };
212 
213 #ifdef SUT_DECODE_ENABLE
214 constexpr uint8_t ASTC_HEAD_BYTES = 16;
215 constexpr uint8_t SUT_HEAD_BYTES = 16
216 constexpr uint32_t SUT_FILE_SIGNATURE = 0x5CA1AB13;
217 #ifdef SUT_PATH_X64
218 static const std::string g_textureSuperDecSo = "/system/lib64/module/hms/graphic/libtextureSuperDecompress.z.so";
219 #else
220 static const std::string g_textureSuperDecSo = "/system/lib/module/hms/graphic/libtextureSuperDecompress.z.so";
221 #endif
222 constexpr uint8_t EXPAND_ASTC_INFO_MAX_DEC = 16; // reserve max 16 groups TLV info
223 
224 struct AstcOutInfo {
225     uint8_t *astcBuf;
226     int32_t astcBytes;
227     uint8_t expandNums; // groupNum of TLV extInfo
228     uint8_t expandInfoType[EXPAND_ASTC_INFO_MAX_DEC];
229     int32_t expandInfoBytes[EXPAND_ASTC_INFO_MAX_DEC];
230     uint8_t *expandInfoBuf[EXPAND_ASTC_INFO_MAX_DEC];
231     int32_t expandInfoCapacity[EXPAND_ASTC_INFO_MAX_DEC];
232     int32_t expandTotalBytes;
233     int32_t pureSutBytes;
234 };
235 
236 struct SutInInfo {
237     const uint8_t *sutBuf;
238     int32_t sutBytes;
239 };
240 
241 using GetSuperCompressAstcSize = size_t (*)(const uint8_t *, size_t);
242 using SuperDecompressTexture = bool (*)(const SutInInfo &, AstcOutInfo &);
243 using IsSut = bool (*)(const uint8_t *, size_t);
244 using GetTextureInfoFromSut = bool (*)(const uint8_t *, size_t, uint32_t &, uint32_t &, uint32_t &);
245 using GetExpandInfoFromSut = bool (*)(const SutInInfo &, AstcOutInfo &, bool);
246 class SutDecSoManager {
247 public:
248     SutDecSoManager();
249     ~SutDecSoManager();
250     bool LoadSutDecSo();
251     GetSuperCompressAstcSize sutDecSoGetSizeFunc_;
252     SuperDecompressTexture sutDecSoDecFunc_;
253     GetTextureInfoFromSut getTextureInfoFunc_;
254     GetExpandInfoFromSut getExpandInfoFromSutFunc_;
255 private:
256     bool sutDecSoOpened_;
257     void *textureDecSoHandle_;
258     void DlcloseHandle();
259     std::mutex sutDecSoMutex_ = {};
260 };
261 
262 static SutDecSoManager g_sutDecSoManager;
263 
SutDecSoManager()264 SutDecSoManager::SutDecSoManager()
265 {
266     sutDecSoOpened_ = false;
267     textureDecSoHandle_ = nullptr;
268     sutDecSoGetSizeFunc_ = nullptr;
269     sutDecSoDecFunc_ = nullptr;
270     getTextureInfoFunc_ = nullptr;
271     getExpandInfoFromSutFunc_ = nullptr;
272 }
273 
~SutDecSoManager()274 SutDecSoManager::~SutDecSoManager()
275 {
276     bool cond = (!sutDecSoOpened_ || textureDecSoHandle_ == nullptr);
277     CHECK_DEBUG_RETURN_LOG(cond, "[ImageSource] astcenc dec so is not be opened when dlclose!");
278     cond = dlclose(textureDecSoHandle_) != 0;
279     CHECK_ERROR_RETURN_LOG(cond, "[ImageSource] astcenc dlclose failed: %{public}s!", g_textureSuperDecSo.c_str());
280 }
281 
CheckClBinIsExist(const std::string & name)282 static bool CheckClBinIsExist(const std::string &name)
283 {
284     return (access(name.c_str(), F_OK) != -1); // -1 means that the file is  not exist
285 }
286 
DlcloseHandle()287 void SutDecSoManager::DlcloseHandle()
288 {
289     if (textureDecSoHandle_ != nullptr) {
290         dlclose(textureDecSoHandle_);
291         textureDecSoHandle_ = nullptr;
292     }
293 }
294 
LoadSutDecSo()295 bool SutDecSoManager::LoadSutDecSo()
296 {
297     std::lock_guard<std::mutex> lock(sutDecSoMutex_);
298     if (!sutDecSoOpened_) {
299         if (!CheckClBinIsExist(g_textureSuperDecSo)) {
300             IMAGE_LOGE("[ImageSource] %{public}s! is not found", g_textureSuperDecSo.c_str());
301             return false;
302         }
303         textureDecSoHandle_ = dlopen(g_textureSuperDecSo.c_str(), 1);
304         if (textureDecSoHandle_ == nullptr) {
305             IMAGE_LOGE("[ImageSource] astc libtextureSuperDecompress dlopen failed!");
306             return false;
307         }
308         sutDecSoGetSizeFunc_ =
309             reinterpret_cast<GetSuperCompressAstcSize>(dlsym(textureDecSoHandle_, "GetSuperCompressAstcSize"));
310         if (sutDecSoGetSizeFunc_ == nullptr) {
311             IMAGE_LOGE("[ImageSource] astc GetSuperCompressAstcSize dlsym failed!");
312             DlcloseHandle();
313             return false;
314         }
315         sutDecSoDecFunc_ =
316             reinterpret_cast<SuperDecompressTexture>(dlsym(textureDecSoHandle_, "SuperDecompressTextureTlv"));
317         if (sutDecSoDecFunc_ == nullptr) {
318             IMAGE_LOGE("[ImageSource] astc SuperDecompressTextureTlv dlsym failed!");
319             DlcloseHandle();
320             return false;
321         }
322         getTextureInfoFunc_ =
323             reinterpret_cast<GetTextureInfoFromSut>(dlsym(textureDecSoHandle_, "GetTextureInfoFromSut"));
324         if (getTextureInfoFunc_ == nullptr) {
325             IMAGE_LOGE("[ImageSource] astc GetTextureInfoFromSut dlsym failed!");
326             DlcloseHandle();
327             return false;
328         }
329         getExpandInfoFromSutFunc_ =
330             reinterpret_cast<GetExpandInfoFromSut>(dlsym(textureDecSoHandle_, "GetExpandInfoFromSut"));
331         if (getExpandInfoFromSutFunc_ == nullptr) {
332             IMAGE_LOGE("[ImageSource] astc GetExpandInfoFromSut dlsym failed!");
333             DlcloseHandle();
334             return false;
335         }
336         sutDecSoOpened_ = true;
337     }
338     return true;
339 }
340 #endif
341 
342 const auto KEY_SIZE = 2;
343 const static std::string DEFAULT_EXIF_VALUE = "default_exif_value";
344 const static std::map<std::string, uint32_t> ORIENTATION_INT_MAP = {
345     {"Top-left", 0},
346     {"Bottom-right", 180},
347     {"Right-top", 90},
348     {"Left-bottom", 270},
349 };
350 const static string IMAGE_DELAY_TIME = "DelayTime";
351 const static string IMAGE_DISPOSAL_TYPE = "DisposalType";
352 const static string IMAGE_GIFLOOPCOUNT_TYPE = "GIFLoopCount";
353 const static int32_t ZERO = 0;
354 
355 PluginServer &ImageSource::pluginServer_ = ImageUtils::GetPluginServer();
356 ImageSource::FormatAgentMap ImageSource::formatAgentMap_ = InitClass();
357 
358 #ifdef HEIF_HW_DECODE_ENABLE
IsSecureMode(const std::string & name)359 static bool IsSecureMode(const std::string &name)
360 {
361     std::string prefix = ".secure";
362     bool cond = name.length() <= prefix.length();
363     CHECK_ERROR_RETURN_RET(cond, false);
364     return name.rfind(prefix) == (name.length() - prefix.length());
365 }
366 #endif
367 
IsSupportHeif()368 static bool IsSupportHeif()
369 {
370 #ifdef HEIF_HW_DECODE_ENABLE
371     sptr<HDI::Codec::V3_0::ICodecComponentManager> manager =
372             HDI::Codec::V3_0::ICodecComponentManager::Get(false);
373     bool cond = manager == nullptr;
374     CHECK_ERROR_RETURN_RET(cond, false);
375     int32_t compCnt = 0;
376     int32_t ret = manager->GetComponentNum(compCnt);
377     cond = (ret != HDF_SUCCESS || compCnt <= 0);
378     CHECK_ERROR_RETURN_RET(cond, false);
379     std::vector<HDI::Codec::V3_0::CodecCompCapability> capList(compCnt);
380     ret = manager->GetComponentCapabilityList(capList, compCnt);
381     cond = (ret != HDF_SUCCESS || capList.empty());
382     CHECK_ERROR_RETURN_RET(cond, false);
383     for (const auto& cap : capList) {
384         if (cap.role == HDI::Codec::V3_0::MEDIA_ROLETYPE_VIDEO_HEVC &&
385             cap.type == HDI::Codec::V3_0::VIDEO_DECODER && !IsSecureMode(cap.compName)) {
386             return true;
387         }
388     }
389 #endif
390     return false;
391 }
392 
GetSupportedFormats(set<string> & formats)393 uint32_t ImageSource::GetSupportedFormats(set<string> &formats)
394 {
395     IMAGE_LOGD("[ImageSource]get supported image type.");
396     formats.clear();
397     vector<ClassInfo> classInfos;
398     uint32_t ret =
399         pluginServer_.PluginServerGetClassInfo<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT, classInfos);
400     bool cond = ret != SUCCESS;
401     CHECK_ERROR_RETURN_RET_LOG(cond, ret,
402                                "[ImageSource]get class info from plugin server failed, ret:%{public}u.", ret);
403 
404     for (auto &info : classInfos) {
405         map<string, AttrData> &capbility = info.capabilities;
406         auto iter = capbility.find(IMAGE_ENCODE_FORMAT);
407         if (iter == capbility.end()) {
408             continue;
409         }
410 
411         AttrData &attr = iter->second;
412         const string *format = nullptr;
413         if (attr.GetValue(format) != SUCCESS || format == nullptr) {
414             IMAGE_LOGE("[ImageSource]attr data get format failed.");
415             continue;
416         }
417 
418         if (*format == InnerFormat::RAW_FORMAT) {
419             formats.insert(std::begin(InnerFormat::RAW_EXTENDED_FORMATS), std::end(InnerFormat::RAW_EXTENDED_FORMATS));
420         } else {
421             formats.insert(*format);
422         }
423     }
424 
425     static bool isSupportHeif = IsSupportHeif();
426     if (isSupportHeif) {
427         formats.insert(ImageUtils::GetEncodedHeifFormat());
428     }
429     return SUCCESS;
430 }
431 
DoImageSourceCreate(std::function<unique_ptr<SourceStream> (void)> stream,const SourceOptions & opts,uint32_t & errorCode,const string traceName)432 unique_ptr<ImageSource> ImageSource::DoImageSourceCreate(std::function<unique_ptr<SourceStream>(void)> stream,
433     const SourceOptions &opts, uint32_t &errorCode, const string traceName)
434 {
435     ImageTrace imageTrace(traceName);
436     IMAGE_LOGD("[ImageSource]DoImageSourceCreate IN.");
437     errorCode = ERR_IMAGE_SOURCE_DATA;
438     auto streamPtr = stream();
439     if (streamPtr == nullptr) {
440         IMAGE_LOGD("[ImageSource]failed to create source stream.");
441         ReportCreateImageSourceFault(opts.size.width, opts.size.height, traceName, "stream failed");
442         return nullptr;
443     }
444 
445     auto sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
446     if (sourcePtr == nullptr) {
447         IMAGE_LOGE("[ImageSource]failed to create ImageSource.");
448         ReportCreateImageSourceFault(opts.size.width, opts.size.height, traceName, "failed to create ImageSource");
449         return nullptr;
450     }
451     sourcePtr->SetSource(traceName);
452     errorCode = SUCCESS;
453     return unique_ptr<ImageSource>(sourcePtr);
454 }
455 
CreateImageSource(unique_ptr<istream> is,const SourceOptions & opts,uint32_t & errorCode)456 unique_ptr<ImageSource> ImageSource::CreateImageSource(unique_ptr<istream> is, const SourceOptions &opts,
457     uint32_t &errorCode)
458 {
459     IMAGE_LOGD("[ImageSource]create Imagesource with stream.");
460     ImageDataStatistics imageDataStatistics("[ImageSource]CreateImageSource with stream.");
461     return DoImageSourceCreate(
462         [&is]() {
463             auto stream = IstreamSourceStream::CreateSourceStream(move(is));
464             if (stream == nullptr) {
465                 IMAGE_LOGE("[ImageSource]failed to create istream source stream.");
466             }
467             return stream;
468         },
469         opts, errorCode, "CreateImageSource by istream");
470 }
471 
CreateImageSource(const uint8_t * data,uint32_t size,const SourceOptions & opts,uint32_t & errorCode)472 unique_ptr<ImageSource> ImageSource::CreateImageSource(const uint8_t *data, uint32_t size, const SourceOptions &opts,
473     uint32_t &errorCode)
474 {
475     if (size > MAX_SOURCE_SIZE) {
476         IMAGE_LOGE("%{public}s input size %{public}u is too large.", __func__, size);
477         errorCode = ERR_IMAGE_TOO_LARGE;
478         return nullptr;
479     }
480     IMAGE_LOGD("[ImageSource]create Imagesource with buffer.");
481     ImageDataStatistics imageDataStatistics("[ImageSource]CreateImageSource with buffer.");
482     if (data == nullptr || size == 0) {
483         IMAGE_LOGE("[ImageSource]parameter error.");
484         errorCode = ERR_MEDIA_INVALID_PARAM;
485         return nullptr;
486     }
487     auto imageSource = DoImageSourceCreate(
488         [&data, &size]() {
489             auto streamPtr = DecodeBase64(data, size);
490             if (streamPtr == nullptr) {
491                 streamPtr = BufferSourceStream::CreateSourceStream(data, size);
492             }
493             if (streamPtr == nullptr) {
494                 IMAGE_LOGE("[ImageSource]failed to create buffer source stream.");
495             }
496             return streamPtr;
497         },
498         opts, errorCode, "CreateImageSource by data");
499     if (imageSource != nullptr) {
500         imageSource->SetSrcBuffer(data, size);
501     }
502     return imageSource;
503 }
504 
CreateImageSource(const std::string & pathName,const SourceOptions & opts,uint32_t & errorCode)505 unique_ptr<ImageSource> ImageSource::CreateImageSource(const std::string &pathName, const SourceOptions &opts,
506     uint32_t &errorCode)
507 {
508     IMAGE_LOGD("[ImageSource]create Imagesource with pathName.");
509     ImageDataStatistics imageDataStatistics("[ImageSource]CreateImageSource with pathName.");
510     if (pathName.size() == SIZE_ZERO) {
511         IMAGE_LOGE("[ImageSource]parameter error.");
512         return nullptr;
513     }
514     auto imageSource = DoImageSourceCreate(
515         [&pathName]() {
516             auto streamPtr = DecodeBase64(pathName);
517             if (streamPtr == nullptr) {
518                 streamPtr = FileSourceStream::CreateSourceStream(pathName);
519             }
520             bool cond = (streamPtr == nullptr);
521             CHECK_DEBUG_PRINT_LOG(cond, "[ImageSource]failed to create file path source stream");
522             return streamPtr;
523         },
524         opts, errorCode, "CreateImageSource by path");
525     if (imageSource != nullptr) {
526         imageSource->SetSrcFilePath(pathName);
527     }
528     return imageSource;
529 }
530 
CreateImageSource(const int fd,const SourceOptions & opts,uint32_t & errorCode)531 unique_ptr<ImageSource> ImageSource::CreateImageSource(const int fd, const SourceOptions &opts, uint32_t &errorCode)
532 {
533     IMAGE_LOGD("[ImageSource]create Imagesource with fd.");
534     ImageDataStatistics imageDataStatistics("[ImageSource]CreateImageSource with fd.");
535     auto imageSource = DoImageSourceCreate(
536         [&fd]() {
537             auto streamPtr = FileSourceStream::CreateSourceStream(fd);
538             if (streamPtr == nullptr) {
539                 IMAGE_LOGE("[ImageSource]failed to create file fd source stream.");
540             }
541             return streamPtr;
542         },
543         opts, errorCode, "CreateImageSource by fd");
544     if (imageSource != nullptr) {
545         imageSource->SetSrcFd(fd);
546     }
547     return imageSource;
548 }
549 
CreateImageSource(const int fd,int32_t offset,int32_t length,const SourceOptions & opts,uint32_t & errorCode)550 unique_ptr<ImageSource> ImageSource::CreateImageSource(const int fd, int32_t offset, int32_t length,
551     const SourceOptions &opts, uint32_t &errorCode)
552 {
553     IMAGE_LOGD("[ImageSource]create Imagesource with fd offset and length.");
554     ImageDataStatistics imageDataStatistics("[ImageSource]CreateImageSource with offset.");
555     auto imageSource = DoImageSourceCreate(
556         [&fd, offset, length]() {
557             auto streamPtr = FileSourceStream::CreateSourceStream(fd, offset, length);
558             if (streamPtr == nullptr) {
559                 IMAGE_LOGE("[ImageSource]failed to create file fd source stream.");
560             }
561             return streamPtr;
562         },
563         opts, errorCode, "CreateImageSource by fd offset and length");
564     if (imageSource != nullptr) {
565         imageSource->SetSrcFd(fd);
566     }
567     return imageSource;
568 }
569 
CreateIncrementalImageSource(const IncrementalSourceOptions & opts,uint32_t & errorCode)570 unique_ptr<ImageSource> ImageSource::CreateIncrementalImageSource(const IncrementalSourceOptions &opts,
571     uint32_t &errorCode)
572 {
573     IMAGE_LOGD("[ImageSource]create incremental ImageSource.");
574     ImageDataStatistics imageDataStatistics("[ImageSource]CreateIncrementalImageSource width = %d, height = %d," \
575         "format = %d", opts.sourceOptions.size.width, opts.sourceOptions.size.height, opts.sourceOptions.pixelFormat);
576     auto sourcePtr = DoImageSourceCreate(
577         [&opts]() {
578             auto streamPtr = IncrementalSourceStream::CreateSourceStream(opts.incrementalMode);
579             bool cond = streamPtr == nullptr;
580             CHECK_ERROR_PRINT_LOG(cond, "[ImageSource]failed to create incremental source stream.");
581             return streamPtr;
582         },
583         opts.sourceOptions, errorCode, "CreateImageSource by fd");
584     if (sourcePtr != nullptr) {
585         sourcePtr->SetIncrementalSource(true);
586     }
587     return sourcePtr;
588 }
589 
Reset()590 void ImageSource::Reset()
591 {
592     // if use skia now, no need reset
593     bool cond = mainDecoder_ != nullptr && mainDecoder_->HasProperty(SKIA_DECODER);
594     CHECK_ERROR_RETURN(cond);
595     imageStatusMap_.clear();
596     decodeState_ = SourceDecodingState::UNRESOLVED;
597     sourceStreamPtr_->Seek(0);
598     mainDecoder_ = nullptr;
599 }
600 
CreatePixelMapEx(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)601 unique_ptr<PixelMap> ImageSource::CreatePixelMapEx(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
602 {
603     if (opts.desiredSize.width < 0 || opts.desiredSize.height < 0) {
604         IMAGE_LOGE("desiredSize is invalid");
605         errorCode = ERR_IMAGE_INVALID_PARAMETER;
606         return nullptr;
607     }
608     ImageTrace imageTrace("ImageSource::CreatePixelMapEx, index:%u, desiredSize:(%d, %d)", index,
609         opts.desiredSize.width, opts.desiredSize.height);
610     IMAGE_LOGD("CreatePixelMapEx imageId_: %{public}lu, desiredPixelFormat: %{public}d,"
611         "desiredSize: (%{public}d, %{public}d)",
612         static_cast<unsigned long>(imageId_), opts.desiredPixelFormat, opts.desiredSize.width, opts.desiredSize.height);
613 
614 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
615     if (!isAstc_.has_value()) {
616         ImagePlugin::DataStreamBuffer outData;
617         uint32_t res = GetData(outData, ASTC_HEADER_SIZE);
618         if (res == SUCCESS) {
619             isAstc_ = IsASTC(outData.inputStreamBuffer, outData.dataSize);
620         }
621     }
622     if (isAstc_.has_value() && isAstc_.value()) {
623         return CreatePixelMapForASTC(errorCode, opts);
624     }
625 #endif
626 
627     if (opts.desiredPixelFormat == PixelFormat::ASTC_4x4) {
628         return CreatePixelAstcFromImageFile(index, opts, errorCode);
629     }
630 
631     if (IsSpecialYUV()) {
632         opts_ = opts;
633         return CreatePixelMapForYUV(errorCode);
634     }
635 
636     DumpInputData();
637     return CreatePixelMap(index, opts, errorCode);
638 }
639 
IsExtendedCodec(AbsImageDecoder * decoder)640 static bool IsExtendedCodec(AbsImageDecoder *decoder)
641 {
642     const static string ENCODED_FORMAT_KEY = "EncodedFormat";
643     bool cond = decoder != nullptr && decoder->HasProperty(ENCODED_FORMAT_KEY);
644     CHECK_ERROR_RETURN_RET(cond, true);
645     return false;
646 }
647 
IsSizeVailed(const Size & size)648 static inline bool IsSizeVailed(const Size &size)
649 {
650     return (size.width != INT_ZERO && size.height != INT_ZERO);
651 }
652 
CopySize(const Size & src,Size & dst)653 static inline void CopySize(const Size &src, Size &dst)
654 {
655     dst.width = src.width;
656     dst.height = src.height;
657 }
658 
IsDensityChange(int32_t srcDensity,int32_t wantDensity)659 static inline bool IsDensityChange(int32_t srcDensity, int32_t wantDensity)
660 {
661     return (srcDensity != 0 && wantDensity != 0 && srcDensity != wantDensity);
662 }
663 
GetScalePropByDensity(int32_t prop,int32_t srcDensity,int32_t wantDensity)664 static inline int32_t GetScalePropByDensity(int32_t prop, int32_t srcDensity, int32_t wantDensity)
665 {
666     bool cond = srcDensity != 0;
667     int32_t ret = (prop * wantDensity + (srcDensity >> 1)) / srcDensity;
668     CHECK_ERROR_RETURN_RET(cond, ret);
669     return prop;
670 }
671 
TransformSizeWithDensity(const Size & srcSize,int32_t srcDensity,const Size & wantSize,int32_t wantDensity,Size & dstSize)672 void ImageSource::TransformSizeWithDensity(const Size &srcSize, int32_t srcDensity, const Size &wantSize,
673     int32_t wantDensity, Size &dstSize)
674 {
675     if (IsSizeVailed(wantSize)) {
676         CopySize(wantSize, dstSize);
677     } else {
678         CopySize(srcSize, dstSize);
679     }
680 
681     if (IsDensityChange(srcDensity, wantDensity)) {
682         dstSize.width = GetScalePropByDensity(dstSize.width, srcDensity, wantDensity);
683         dstSize.height = GetScalePropByDensity(dstSize.height, srcDensity, wantDensity);
684     }
685 }
686 
NotifyDecodeEvent(set<DecodeListener * > & listeners,DecodeEvent event,std::unique_lock<std::mutex> * guard)687 static void NotifyDecodeEvent(set<DecodeListener *> &listeners, DecodeEvent event, std::unique_lock<std::mutex> *guard)
688 {
689     if (listeners.size() == SIZE_ZERO) {
690         return;
691     }
692     for (auto listener : listeners) {
693         if (guard != nullptr) {
694             guard->unlock();
695         }
696         listener->OnEvent(static_cast<int>(event));
697         if (guard != nullptr) {
698             guard->lock();
699         }
700     }
701 }
702 
IsDecodeHdrImage(const DecodeOptions & opts)703 bool ImageSource::IsDecodeHdrImage(const DecodeOptions &opts)
704 {
705     ParseHdrType();
706     return (opts.desiredDynamicRange == DecodeDynamicRange::AUTO && sourceHdrType_ > ImageHdrType::SDR) ||
707         opts.desiredDynamicRange == DecodeDynamicRange::HDR;
708 }
709 
IsSvgUseDma(const DecodeOptions & opts)710 bool ImageSource::IsSvgUseDma(const DecodeOptions &opts)
711 {
712     ImageInfo info;
713     GetImageInfo(FIRST_FRAME, info);
714     return info.encodedFormat == IMAGE_SVG_FORMAT && opts.allocatorType == AllocatorType::DMA_ALLOC;
715 }
716 
ConvertAutoAllocatorType(const DecodeOptions & opts)717 AllocatorType ImageSource::ConvertAutoAllocatorType(const DecodeOptions &opts)
718 {
719     ImageInfo info;
720     GetImageInfo(FIRST_FRAME, info);
721     ParseHdrType();
722     if (IsDecodeHdrImage(opts)) {
723         return AllocatorType::DMA_ALLOC;
724     }
725     if (opts.desiredPixelFormat == PixelFormat::ARGB_8888 || info.encodedFormat == IMAGE_SVG_FORMAT) {
726         return AllocatorType::SHARE_MEM_ALLOC;
727     }
728     if (ImageUtils::IsSizeSupportDma(info.size)) {
729         return AllocatorType::DMA_ALLOC;
730     }
731     return AllocatorType::SHARE_MEM_ALLOC;
732 }
733 
ConvertAllocatorType(ImageSource * imageSource,int32_t allocatorType,DecodeOptions & decodeOpts)734 static AllocatorType ConvertAllocatorType(ImageSource *imageSource, int32_t allocatorType, DecodeOptions& decodeOpts)
735 {
736     switch (allocatorType) {
737         case DMA_ALLOC:
738             return AllocatorType::DMA_ALLOC;
739         case SHARE_MEMORY_ALLOC:
740             return AllocatorType::SHARE_MEM_ALLOC;
741         case AUTO_ALLOC:
742         default:
743             return imageSource->ConvertAutoAllocatorType(decodeOpts);
744     }
745 }
746 
IsSupportAllocatorType(DecodeOptions & decOps,int32_t allocatorType)747 bool ImageSource::IsSupportAllocatorType(DecodeOptions& decOps, int32_t allocatorType)
748 {
749     decOps.isAppUseAllocator = true;
750     decOps.allocatorType = ConvertAllocatorType(this, allocatorType, decOps);
751     if (decOps.allocatorType == AllocatorType::SHARE_MEM_ALLOC && IsDecodeHdrImage(decOps)) {
752         IMAGE_LOGE("%{public}s Hdr image can't use share memory allocator", __func__);
753         return false;
754     } else if (!IsDecodeHdrImage(decOps) && decOps.allocatorType == AllocatorType::DMA_ALLOC &&
755         decOps.desiredPixelFormat == PixelFormat::ARGB_8888) {
756         IMAGE_LOGE("%{public}s SDR image can't set ARGB_8888 and DMA_ALLOC at the same time!", __func__);
757         return false;
758     } else if (IsSvgUseDma(decOps)) {
759         IMAGE_LOGE("%{public}s Svg image can't use dma allocator", __func__);
760         return false;
761     }
762     return true;
763 }
764 
FreeContextBuffer(const Media::CustomFreePixelMap & func,AllocatorType allocType,PlImageBuffer & buffer)765 static void FreeContextBuffer(const Media::CustomFreePixelMap &func, AllocatorType allocType, PlImageBuffer &buffer)
766 {
767     if (func != nullptr) {
768         func(buffer.buffer, buffer.context, buffer.bufferSize);
769         return;
770     }
771 
772 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
773     if (allocType == AllocatorType::SHARE_MEM_ALLOC) {
774         int *fd = static_cast<int *>(buffer.context);
775         if (buffer.buffer != nullptr) {
776             ::munmap(buffer.buffer, buffer.bufferSize);
777             buffer.buffer = nullptr;
778         }
779         if (fd != nullptr) {
780             ::close(*fd);
781         }
782         return;
783     } else if (allocType == AllocatorType::DMA_ALLOC) {
784         if (buffer.buffer != nullptr) {
785             ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer *>(buffer.context));
786             buffer.context = nullptr;
787         }
788     } else if (allocType == AllocatorType::HEAP_ALLOC) {
789         if (buffer.buffer != nullptr) {
790             free(buffer.buffer);
791             buffer.buffer = nullptr;
792         }
793     }
794 #else
795     if (buffer.buffer != nullptr) {
796         free(buffer.buffer);
797         buffer.buffer = nullptr;
798     }
799 #endif
800 }
801 
ContextToAddrInfos(DecodeContext & context,PixelMapAddrInfos & addrInfos)802 void ImageSource::ContextToAddrInfos(DecodeContext &context, PixelMapAddrInfos &addrInfos)
803 {
804     addrInfos.addr = static_cast<uint8_t *>(context.pixelsBuffer.buffer);
805     addrInfos.context = static_cast<uint8_t *>(context.pixelsBuffer.context);
806     addrInfos.size = context.pixelsBuffer.bufferSize;
807     addrInfos.type = context.allocatorType;
808     addrInfos.func = context.freeFunc;
809 }
810 
IsSupportAstcZeroCopy(const Size & size)811 bool IsSupportAstcZeroCopy(const Size &size)
812 {
813     return ImageSystemProperties::GetAstcEnabled() && size.width * size.height >= ASTC_SIZE;
814 }
815 
IsSupportDma(const DecodeOptions & opts,const ImageInfo & info,bool hasDesiredSizeOptions)816 bool IsSupportDma(const DecodeOptions &opts, const ImageInfo &info, bool hasDesiredSizeOptions)
817 {
818 #if defined(_WIN32) || defined(_APPLE) || defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
819     IMAGE_LOGE("Unsupport dma mem alloc");
820     return false;
821 #else
822     // used for test surfacebuffer
823     bool cond = ImageSystemProperties::GetSurfaceBufferEnabled() &&
824         ImageUtils::IsSizeSupportDma(hasDesiredSizeOptions ? opts.desiredSize : info.size);
825     CHECK_ERROR_RETURN_RET(cond, true);
826 
827     if (ImageSystemProperties::GetDmaEnabled() && ImageUtils::IsFormatSupportDma(opts.desiredPixelFormat)) {
828         return ImageUtils::IsSizeSupportDma(hasDesiredSizeOptions ? opts.desiredSize : info.size) &&
829             (ImageUtils::IsWidthAligned(opts.desiredSize.width)
830             || opts.preferDma);
831     }
832     return false;
833 #endif
834 }
835 
InitDecodeContext(const DecodeOptions & opts,const ImageInfo & info,const MemoryUsagePreference & preference,bool hasDesiredSizeOptions,PlImageInfo & plInfo)836 DecodeContext ImageSource::InitDecodeContext(const DecodeOptions &opts, const ImageInfo &info,
837     const MemoryUsagePreference &preference, bool hasDesiredSizeOptions, PlImageInfo& plInfo)
838 {
839     DecodeContext context;
840     context.isAppUseAllocator = opts.isAppUseAllocator;
841     context.photoDesiredPixelFormat = opts.photoDesiredPixelFormat;
842     if (opts.allocatorType != AllocatorType::DEFAULT) {
843         context.allocatorType = opts.allocatorType;
844     } else {
845         if ((preference == MemoryUsagePreference::DEFAULT && IsSupportDma(opts, info, hasDesiredSizeOptions)) ||
846             info.encodedFormat == IMAGE_HEIF_FORMAT || info.encodedFormat == IMAGE_HEIC_FORMAT ||
847             ImageSystemProperties::GetDecodeDmaEnabled()) {
848             IMAGE_LOGD("[ImageSource] allocatorType is DMA_ALLOC");
849             context.allocatorType = AllocatorType::DMA_ALLOC;
850         } else {
851             context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
852         }
853     }
854     if (opts.desiredPixelFormat == PixelFormat::ARGB_8888) {
855         IMAGE_LOGD("%{public}s ARGB use SHARE_MEM_ALLOC", __func__);
856         context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
857         context.isAppUseAllocator = true;
858     }
859 
860     context.info.pixelFormat = plInfo.pixelFormat;
861     ImageHdrType hdrType = sourceHdrType_;
862     if (opts_.desiredDynamicRange == DecodeDynamicRange::SDR && !IsSingleHdrImage(hdrType)) {
863         // If the image is a single-layer HDR, it needs to be decoded into HDR first and then converted into SDR.
864         hdrType = ImageHdrType::SDR;
865     }
866     if (hdrType > ImageHdrType::SDR) {
867         // hdr pixelmap need use surfacebuffer.
868         context.allocatorType = AllocatorType::DMA_ALLOC;
869     }
870     context.hdrType = hdrType;
871     IMAGE_LOGD("[ImageSource] sourceHdrType_:%{public}d, deocdeHdrType:%{public}d", sourceHdrType_, hdrType);
872     if (IsSingleHdrImage(hdrType)) {
873         PixelFormat format = PixelFormat::RGBA_1010102;
874         if (opts.desiredPixelFormat == PixelFormat::NV12 || opts.desiredPixelFormat == PixelFormat::YCBCR_P010) {
875             format = PixelFormat::YCBCR_P010;
876         } else if (opts.desiredPixelFormat == PixelFormat::NV21 || opts.desiredPixelFormat == PixelFormat::YCRCB_P010) {
877             format = PixelFormat::YCRCB_P010;
878         }
879         context.pixelFormat = format;
880         context.info.pixelFormat = format;
881         plInfo.pixelFormat = format;
882     }
883     return context;
884 }
885 
GetNowTimeMicroSeconds()886 uint64_t ImageSource::GetNowTimeMicroSeconds()
887 {
888     auto now = std::chrono::system_clock::now();
889     return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
890 }
891 
UpdatePlImageInfo(DecodeContext context,ImagePlugin::PlImageInfo & plInfo)892 static void UpdatePlImageInfo(DecodeContext context, ImagePlugin::PlImageInfo &plInfo)
893 {
894     if (context.hdrType > Media::ImageHdrType::SDR) {
895         plInfo.colorSpace = context.colorSpace;
896         plInfo.pixelFormat = context.pixelFormat;
897     }
898 
899     if (plInfo.size.width != context.outInfo.size.width || plInfo.size.height != context.outInfo.size.height) {
900         plInfo.size = context.outInfo.size;
901     }
902     if ((plInfo.pixelFormat == PixelFormat::NV12 || plInfo.pixelFormat == PixelFormat::NV21 ||
903          plInfo.pixelFormat == PixelFormat::YCBCR_P010 || plInfo.pixelFormat == PixelFormat::YCRCB_P010) &&
904         context.yuvInfo.imageSize.width != 0) {
905         plInfo.yuvDataInfo = context.yuvInfo;
906         plInfo.size = context.yuvInfo.imageSize;
907     }
908 }
909 
NeedConvertToYuv(PixelFormat optsPixelFormat,PixelFormat curPixelFormat)910 bool NeedConvertToYuv(PixelFormat optsPixelFormat, PixelFormat curPixelFormat)
911 {
912     return (optsPixelFormat == PixelFormat::NV12 || optsPixelFormat == PixelFormat::NV21) && (
913         curPixelFormat == PixelFormat::RGBA_8888 || curPixelFormat == PixelFormat::ARGB_8888 ||
914         curPixelFormat == PixelFormat::RGB_565 || curPixelFormat == PixelFormat::BGRA_8888 ||
915         curPixelFormat == PixelFormat::RGB_888);
916 }
917 
IsSupportConvertToArgb(PixelMap * pixelMap)918 static bool IsSupportConvertToArgb(PixelMap *pixelMap)
919 {
920     return pixelMap != nullptr && !pixelMap->IsHdr() && pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
921 }
922 
CheckAllocatorTypeValid(const DecodeOptions & opts)923 bool ImageSource::CheckAllocatorTypeValid(const DecodeOptions &opts)
924 {
925     if (opts.isAppUseAllocator && opts.allocatorType == AllocatorType::SHARE_MEM_ALLOC && IsDecodeHdrImage(opts)) {
926         IMAGE_LOGE("HDR image can't use SHARE_MEM_ALLOC");
927         return false;
928     } else if (!IsDecodeHdrImage(opts) && opts.allocatorType == AllocatorType::DMA_ALLOC &&
929         opts.desiredPixelFormat == PixelFormat::ARGB_8888) {
930         IMAGE_LOGE("%{public}s SDR image can't set ARGB_8888 and DMA_ALLOC at the same time!", __func__);
931         return false;
932     }
933     return true;
934 }
935 
IsSrcRectContainsDistRect(const Rect & srcRect,const Rect & dstRect)936 bool IsSrcRectContainsDistRect(const Rect &srcRect, const Rect &dstRect)
937 {
938     if (srcRect.left < 0 || srcRect.top < 0 || srcRect.width <= 0 || srcRect.height <= 0) {
939         return false;
940     }
941     if (dstRect.left < 0 || dstRect.top < 0 || dstRect.width <= 0 || dstRect.height <= 0) {
942         return false;
943     }
944     return srcRect.left <= dstRect.left && srcRect.top <= dstRect.top &&
945         (srcRect.left + srcRect.width) >= (dstRect.left + dstRect.width) &&
946         (srcRect.top + srcRect.height) >= (dstRect.top + dstRect.height);
947 }
948 
CheckCropRectValid(const DecodeOptions & opts)949 bool ImageSource::CheckCropRectValid(const DecodeOptions &opts)
950 {
951     Rect srcRect = {0, 0, 0, 0};
952     if (opts.cropAndScaleStrategy == CropAndScaleStrategy::DEFAULT) {
953         return true;
954     }
955     ImageInfo info;
956     if (GetImageInfo(FIRST_FRAME, info) != SUCCESS) {
957         return false;
958     }
959     srcRect.width = info.size.width;
960     srcRect.height = info.size.height;
961     if (opts.cropAndScaleStrategy == CropAndScaleStrategy::SCALE_FIRST &&
962         (opts.desiredSize.width != 0 || opts.desiredSize.height != 0)) {
963         srcRect.width = opts.desiredSize.width;
964         srcRect.height = opts.desiredSize.height;
965     }
966     return IsSrcRectContainsDistRect(srcRect, opts.CropRect);
967 }
968 
CheckDecodeOptions(const DecodeOptions & opts)969 bool ImageSource::CheckDecodeOptions(const DecodeOptions &opts)
970 {
971     return CheckAllocatorTypeValid(opts) && CheckCropRectValid(opts);
972 }
973 
CreatePixelMapExtended(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)974 unique_ptr<PixelMap> ImageSource::CreatePixelMapExtended(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
975 {
976     ImageEvent imageEvent;
977     ImageDataStatistics imageDataStatistics("[ImageSource] CreatePixelMapExtended.");
978     uint64_t decodeStartTime = GetNowTimeMicroSeconds();
979     opts_ = opts;
980     ImageInfo info;
981     errorCode = GetImageInfo(FIRST_FRAME, info);
982     ParseHdrType();
983     if (!CheckDecodeOptions(opts)) {
984         IMAGE_LOGI("CheckDecodeOptions failed.");
985         errorCode = ERR_MEDIA_INVALID_OPERATION;
986         return nullptr;
987     }
988 #ifdef IMAGE_QOS_ENABLE
989     if (ImageUtils::IsSizeSupportDma(info.size) && getpid() != gettid()) {
990         OHOS::QOS::SetThreadQos(OHOS::QOS::QosLevel::QOS_USER_INTERACTIVE);
991     }
992 #endif
993     SetDecodeInfoOptions(index, opts, info, imageEvent);
994     ImageTrace imageTrace("CreatePixelMapExtended, info.size:(%d, %d)", info.size.width, info.size.height);
995     if (errorCode != SUCCESS || !IsSizeVailed(info.size)) {
996         IMAGE_LOGE("[ImageSource]get image info failed, ret:%{public}u.", errorCode);
997         imageEvent.SetDecodeErrorMsg("get image info failed, ret:" + std::to_string(errorCode));
998         errorCode = ERR_IMAGE_DATA_ABNORMAL;
999         return nullptr;
1000     }
1001     ImagePlugin::PlImageInfo plInfo;
1002     DecodeContext context = DecodeImageDataToContextExtended(index, info, plInfo, imageEvent, errorCode);
1003     imageDataStatistics.AddTitle("imageSize: [%d, %d], desireSize: [%d, %d], imageFormat: %s, desirePixelFormat: %d,"
1004         "memorySize: %d, memoryType: %d", info.size.width, info.size.height, opts.desiredSize.width,
1005         opts.desiredSize.height, sourceInfo_.encodedFormat.c_str(), opts.desiredPixelFormat,
1006         context.pixelsBuffer.bufferSize, context.allocatorType);
1007     imageDataStatistics.SetRequestMemory(context.pixelsBuffer.bufferSize);
1008     if (errorCode != SUCCESS) {
1009         IMAGE_LOGE("[ImageSource]decode source fail, ret:%{public}u.", errorCode);
1010         imageEvent.SetDecodeErrorMsg("decode source fail, ret:" + std::to_string(errorCode));
1011         return nullptr;
1012     }
1013     bool isHdr = context.hdrType > Media::ImageHdrType::SDR;
1014     auto res = ImageAiProcess(info.size, opts, isHdr, context, plInfo);
1015     if (res != SUCCESS) {
1016         IMAGE_LOGD("[ImageSource] ImageAiProcess fail, isHdr%{public}d, ret:%{public}u.", isHdr, res);
1017         if (opts_.resolutionQuality == ResolutionQuality::HIGH && (IsSizeVailed(opts.desiredSize) &&
1018             (opts_.desiredSize.width != opts.desiredSize.width ||
1019             opts_.desiredSize.height != opts.desiredSize.height))) {
1020             opts_.desiredSize.width = opts.desiredSize.width;
1021             opts_.desiredSize.height = opts.desiredSize.height;
1022         }
1023     }
1024     UpdatePlImageInfo(context, plInfo);
1025 
1026     auto pixelMap = CreatePixelMapByInfos(plInfo, context, errorCode);
1027     if (pixelMap == nullptr) {
1028         return nullptr;
1029     }
1030     if (!context.ifPartialOutput) {
1031         NotifyDecodeEvent(decodeListeners_, DecodeEvent::EVENT_COMPLETE_DECODE, nullptr);
1032     }
1033     if ("image/gif" != sourceInfo_.encodedFormat && "image/webp" != sourceInfo_.encodedFormat) {
1034         IMAGE_LOGD("CreatePixelMapExtended success, imageId:%{public}lu, desiredSize: (%{public}d, %{public}d),"
1035             "imageSize: (%{public}d, %{public}d), hdrType : %{public}d, cost %{public}lu us",
1036             static_cast<unsigned long>(imageId_), opts.desiredSize.width, opts.desiredSize.height, info.size.width,
1037             info.size.height, context.hdrType, static_cast<unsigned long>(GetNowTimeMicroSeconds() - decodeStartTime));
1038     }
1039 
1040     if (CreatExifMetadataByImageSource() == SUCCESS) {
1041         auto metadataPtr = exifMetadata_->Clone();
1042         pixelMap->SetExifMetadata(metadataPtr);
1043     }
1044     if (NeedConvertToYuv(opts.desiredPixelFormat, pixelMap->GetPixelFormat())) {
1045         uint32_t convertRes = ImageFormatConvert::RGBConvertImageFormatOptionUnique(
1046             pixelMap, plInfo.pixelFormat, opts_.desiredPixelFormat);
1047         if (convertRes != SUCCESS) {
1048             IMAGE_LOGE("convert rgb to yuv failed, return origin rgb!");
1049         }
1050     }
1051     if (opts.desiredPixelFormat == PixelFormat::ARGB_8888 && IsSupportConvertToArgb(pixelMap.get())) {
1052         uint32_t convertRes = ConvertArgbAndRgba(pixelMap.get(), PixelFormat::ARGB_8888);
1053         if (convertRes != SUCCESS) {
1054             IMAGE_LOGE("convert RGBA to ARGB failed, return origin RGBA! error:%{public}u", convertRes);
1055         }
1056     }
1057     return pixelMap;
1058 }
1059 
GetValidCropRect(const Rect & src,const Size & size,Rect & dst)1060 static void GetValidCropRect(const Rect &src, const Size& size, Rect &dst)
1061 {
1062     dst.top = src.top;
1063     dst.left = src.left;
1064     dst.width = src.width;
1065     dst.height = src.height;
1066     int32_t dstBottom = dst.top + dst.height;
1067     int32_t dstRight = dst.left + dst.width;
1068     if (dst.top >= 0 && dstBottom > 0 && dstBottom > size.height) {
1069         dst.height = size.height - dst.top;
1070     }
1071     if (dst.left >= 0 && dstRight > 0 && dstRight > size.width) {
1072         dst.width = size.width - dst.left;
1073     }
1074 }
1075 
ResizeCropPixelmap(PixelMap & pixelmap,int32_t srcDensity,int32_t wantDensity,Size & dstSize)1076 static void ResizeCropPixelmap(PixelMap &pixelmap, int32_t srcDensity, int32_t wantDensity, Size &dstSize)
1077 {
1078     ImageInfo info;
1079     pixelmap.GetImageInfo(info);
1080     if (!IsDensityChange(srcDensity, wantDensity)) {
1081         dstSize.width = info.size.width;
1082         dstSize.height = info.size.height;
1083     } else {
1084         dstSize.width = GetScalePropByDensity(info.size.width, srcDensity, wantDensity);
1085         dstSize.height = GetScalePropByDensity(info.size.height, srcDensity, wantDensity);
1086     }
1087 }
1088 
IsYuvFormat(PixelFormat format)1089 bool ImageSource::IsYuvFormat(PixelFormat format)
1090 {
1091     return format == PixelFormat::NV21 || format == PixelFormat::NV12 ||
1092         format == PixelFormat::YCRCB_P010 || format == PixelFormat::YCBCR_P010;
1093 }
1094 
CopyYuvInfo(YUVDataInfo & yuvInfo,ImagePlugin::PlImageInfo & plInfo)1095 static void CopyYuvInfo(YUVDataInfo &yuvInfo, ImagePlugin::PlImageInfo &plInfo)
1096 {
1097     yuvInfo.yWidth = plInfo.yuvDataInfo.yWidth;
1098     yuvInfo.yHeight = plInfo.yuvDataInfo.yHeight;
1099     yuvInfo.uvWidth = plInfo.yuvDataInfo.uvWidth;
1100     yuvInfo.uvHeight = plInfo.yuvDataInfo.uvHeight;
1101     yuvInfo.yStride = plInfo.yuvDataInfo.yStride;
1102     yuvInfo.uStride = plInfo.yuvDataInfo.uStride;
1103     yuvInfo.vStride = plInfo.yuvDataInfo.vStride;
1104     yuvInfo.uvStride = plInfo.yuvDataInfo.uvStride;
1105     yuvInfo.yOffset = plInfo.yuvDataInfo.yOffset;
1106     yuvInfo.uOffset = plInfo.yuvDataInfo.uOffset;
1107     yuvInfo.vOffset = plInfo.yuvDataInfo.vOffset;
1108     yuvInfo.uvOffset = plInfo.yuvDataInfo.uvOffset;
1109 }
1110 
ResizePixelMap(std::unique_ptr<PixelMap> & pixelMap,uint64_t imageId,DecodeOptions & opts)1111 static bool ResizePixelMap(std::unique_ptr<PixelMap>& pixelMap, uint64_t imageId, DecodeOptions &opts)
1112 {
1113     ImageUtils::DumpPixelMapIfDumpEnabled(pixelMap, imageId);
1114     if (opts.desiredSize.height != pixelMap->GetHeight() ||
1115         opts.desiredSize.width != pixelMap->GetWidth()) {
1116         if (ImageSource::IsYuvFormat(pixelMap->GetPixelFormat())) {
1117 #ifdef EXT_PIXEL
1118             auto pixelYuv = reinterpret_cast<PixelYuvExt *>(pixelMap.get());
1119             bool cond = !pixelYuv->resize(opts.desiredSize.width, opts.desiredSize.height);
1120             CHECK_ERROR_RETURN_RET(cond, false);
1121 #else
1122             auto pixelYuv = reinterpret_cast<PixelYuv *>(pixelMap.get());
1123             bool cond = !pixelYuv->resize(opts.desiredSize.width, opts.desiredSize.height);
1124             CHECK_ERROR_RETURN_RET(cond, false);
1125 #endif
1126         } else {
1127             float xScale = static_cast<float>(opts.desiredSize.width) / pixelMap->GetWidth();
1128             float yScale = static_cast<float>(opts.desiredSize.height) / pixelMap->GetHeight();
1129             bool cond = !pixelMap->resize(xScale, yScale);
1130             CHECK_ERROR_RETURN_RET(cond, false);
1131         }
1132         // dump pixelMap after resize
1133         ImageUtils::DumpPixelMapIfDumpEnabled(pixelMap, imageId);
1134     }
1135     return true;
1136 }
1137 
1138 // add graphic colorspace object to pixelMap.
SetPixelMapColorSpace(ImagePlugin::DecodeContext & context,unique_ptr<PixelMap> & pixelMap,std::unique_ptr<ImagePlugin::AbsImageDecoder> & decoder)1139 void ImageSource::SetPixelMapColorSpace(ImagePlugin::DecodeContext& context, unique_ptr<PixelMap>& pixelMap,
1140     std::unique_ptr<ImagePlugin::AbsImageDecoder>& decoder)
1141 {
1142 #ifdef IMAGE_COLORSPACE_FLAG
1143     bool isSupportICCProfile = (decoder == nullptr) ? false : decoder->IsSupportICCProfile();
1144     if (IsSingleHdrImage(sourceHdrType_)) {
1145         pixelMap->SetToSdrColorSpaceIsSRGB(false);
1146     } else {
1147         if (isSupportICCProfile) {
1148             pixelMap->SetToSdrColorSpaceIsSRGB(decoder->GetPixelMapColorSpace().GetColorSpaceName() ==
1149             ColorManager::SRGB);
1150         }
1151     }
1152     // If the original image is a single-layer HDR, colorSpace needs to be obtained from the DecodeContext.
1153     if (context.hdrType > ImageHdrType::SDR || IsSingleHdrImage(sourceHdrType_)) {
1154         pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(context.grColorSpaceName));
1155         IMAGE_LOGD("hdr set pixelmap colorspace is %{public}d-%{public}d",
1156             context.grColorSpaceName, pixelMap->InnerGetGrColorSpace().GetColorSpaceName());
1157         return ;
1158     }
1159     if (isSupportICCProfile) {
1160         OHOS::ColorManager::ColorSpace grColorSpace = decoder->GetPixelMapColorSpace();
1161         pixelMap->InnerSetColorSpace(grColorSpace);
1162     }
1163 #endif
1164 }
1165 
CreatePixelMapByInfos(ImagePlugin::PlImageInfo & plInfo,ImagePlugin::DecodeContext & context,uint32_t & errorCode)1166 unique_ptr<PixelMap> ImageSource::CreatePixelMapByInfos(ImagePlugin::PlImageInfo &plInfo,
1167     ImagePlugin::DecodeContext& context, uint32_t &errorCode)
1168 {
1169     unique_ptr<PixelMap> pixelMap;
1170     if (IsYuvFormat(plInfo.pixelFormat)) {
1171 #ifdef EXT_PIXEL
1172         pixelMap = make_unique<PixelYuvExt>();
1173 #else
1174         pixelMap = make_unique<PixelYuv>();
1175 #endif
1176     } else {
1177         pixelMap = make_unique<PixelMap>();
1178     }
1179     PixelMapAddrInfos addrInfos;
1180     ContextToAddrInfos(context, addrInfos);
1181     // add graphic colorspace object to pixelMap.
1182     SetPixelMapColorSpace(context, pixelMap, mainDecoder_);
1183     pixelMap->SetPixelsAddr(addrInfos.addr, addrInfos.context, addrInfos.size, addrInfos.type, addrInfos.func);
1184     errorCode = UpdatePixelMapInfo(opts_, plInfo, *(pixelMap.get()), opts_.fitDensity, true);
1185     bool cond = errorCode != SUCCESS;
1186     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
1187     auto saveEditable = pixelMap->IsEditable();
1188     pixelMap->SetEditable(true);
1189     // Need check pixel change:
1190     // 1. pixel size
1191     // 2. crop
1192     // 3. density
1193     // 4. rotate
1194     // 5. format
1195     if (opts_.cropAndScaleStrategy == CropAndScaleStrategy::SCALE_FIRST) {
1196         if (!(ResizePixelMap(pixelMap, imageId_, opts_))) {
1197             IMAGE_LOGE("[ImageSource]Resize pixelmap fail.");
1198             return nullptr;
1199         }
1200     }
1201     const static string SUPPORT_CROP_KEY = "SupportCrop";
1202     if (!mainDecoder_->HasProperty(SUPPORT_CROP_KEY) && opts_.CropRect.width > INT_ZERO &&
1203         opts_.CropRect.height > INT_ZERO) {
1204         Rect crop;
1205         GetValidCropRect(opts_.CropRect, {pixelMap->GetWidth(), pixelMap->GetHeight()}, crop);
1206         errorCode = pixelMap->crop(crop);
1207         if (errorCode != SUCCESS) {
1208             IMAGE_LOGE("[ImageSource]CropRect pixelmap fail, ret:%{public}u.", errorCode);
1209             return nullptr;
1210         }
1211         if (!hasDesiredSizeOptions) {
1212             ResizeCropPixelmap(*pixelMap, sourceInfo_.baseDensity, opts_.fitDensity, opts_.desiredSize);
1213         }
1214     }
1215     // rotateDegrees and rotateNewDegrees
1216     if (!ImageUtils::FloatCompareZero(opts_.rotateDegrees)) {
1217         pixelMap->rotate(opts_.rotateDegrees);
1218     } else if (opts_.rotateNewDegrees != INT_ZERO) {
1219         pixelMap->rotate(opts_.rotateNewDegrees);
1220     }
1221     if (opts_.cropAndScaleStrategy != CropAndScaleStrategy::SCALE_FIRST &&
1222         !(ResizePixelMap(pixelMap, imageId_, opts_))) {
1223         IMAGE_LOGE("[ImageSource]Resize pixelmap fail.");
1224         return nullptr;
1225     }
1226     pixelMap->SetEditable(saveEditable);
1227     return pixelMap;
1228 }
1229 
SetDecodeInfoOptions(uint32_t index,const DecodeOptions & opts,const ImageInfo & info,ImageEvent & imageEvent)1230 void ImageSource::SetDecodeInfoOptions(uint32_t index, const DecodeOptions &opts, const ImageInfo &info,
1231     ImageEvent &imageEvent)
1232 {
1233     DecodeInfoOptions options;
1234     options.sampleSize = opts.sampleSize;
1235     options.rotate = opts.rotateDegrees;
1236     options.editable = opts.editable;
1237     options.sourceWidth = info.size.width;
1238     options.sourceHeight = info.size.height;
1239     options.desireSizeWidth = opts.desiredSize.width;
1240     options.desireSizeHeight = opts.desiredSize.height;
1241     options.desireRegionWidth = opts.CropRect.width;
1242     options.desireRegionHeight = opts.CropRect.height;
1243     options.desireRegionX = opts.CropRect.left;
1244     options.desireRegionY = opts.CropRect.top;
1245     options.desirePixelFormat = static_cast<int32_t>(opts.desiredPixelFormat);
1246     options.photoDesiredPixelFormat = static_cast<int32_t>(opts.photoDesiredPixelFormat);
1247     options.index = index;
1248     options.fitDensity = opts.fitDensity;
1249     options.desireColorSpace = static_cast<int32_t>(opts.desiredColorSpace);
1250     options.mimeType = sourceInfo_.encodedFormat;
1251     options.invokeType = opts.invokeType;
1252     options.imageSource = source_;
1253     imageEvent.SetDecodeInfoOptions(options);
1254 }
1255 
SetDecodeInfoOptions(uint32_t index,const DecodeOptions & opts,const ImagePlugin::PlImageInfo & plInfo,ImageEvent & imageEvent)1256 void ImageSource::SetDecodeInfoOptions(uint32_t index, const DecodeOptions &opts,
1257     const ImagePlugin::PlImageInfo &plInfo, ImageEvent &imageEvent)
1258 {
1259     DecodeInfoOptions options;
1260     options.sampleSize = opts.sampleSize;
1261     options.rotate = opts.rotateDegrees;
1262     options.editable = opts.editable;
1263     options.sourceWidth = plInfo.size.width;
1264     options.sourceHeight = plInfo.size.height;
1265     options.desireSizeWidth = opts.desiredSize.width;
1266     options.desireSizeHeight = opts.desiredSize.height;
1267     options.desireRegionWidth = opts.CropRect.width;
1268     options.desireRegionHeight = opts.CropRect.height;
1269     options.desireRegionX = opts.CropRect.left;
1270     options.desireRegionY = opts.CropRect.top;
1271     options.desirePixelFormat = static_cast<int32_t>(opts.desiredPixelFormat);
1272     options.index = index;
1273     options.fitDensity = opts.fitDensity;
1274     options.desireColorSpace = static_cast<int32_t>(opts.desiredColorSpace);
1275     options.mimeType = sourceInfo_.encodedFormat;
1276     options.invokeType = opts.invokeType;
1277     options.imageSource = source_;
1278     imageEvent.SetDecodeInfoOptions(options);
1279 }
1280 
UpdateDecodeInfoOptions(const ImagePlugin::DecodeContext & context,ImageEvent & imageEvent)1281 void ImageSource::UpdateDecodeInfoOptions(const ImagePlugin::DecodeContext &context, ImageEvent &imageEvent)
1282 {
1283     DecodeInfoOptions &options = imageEvent.GetDecodeInfoOptions();
1284     options.memorySize = context.pixelsBuffer.bufferSize;
1285     options.memoryType = static_cast<int32_t>(context.allocatorType);
1286     options.isHardDecode = context.isHardDecode;
1287     options.hardDecodeError = context.hardDecodeError;
1288 }
1289 
SetImageEventHeifParseErr(ImageEvent & event)1290 void ImageSource::SetImageEventHeifParseErr(ImageEvent &event)
1291 {
1292     bool cond = heifParseErr_ == 0;
1293     CHECK_ERROR_RETURN(cond);
1294     event.GetDecodeInfoOptions().isHardDecode = true;
1295     event.GetDecodeInfoOptions().hardDecodeError
1296         = std::string("parse heif file failed, err: ") + std::to_string(heifParseErr_);
1297 }
1298 
CreatePixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)1299 unique_ptr<PixelMap> ImageSource::CreatePixelMap(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
1300 {
1301     std::unique_lock<std::mutex> guard(decodingMutex_);
1302     opts_ = opts;
1303     bool useSkia = opts_.sampleSize != 1;
1304     if (useSkia) {
1305         // we need reset to initial state to choose correct decoder
1306         Reset();
1307     }
1308     auto iter = GetValidImageStatus(index, errorCode);
1309     if (iter == imageStatusMap_.end()) {
1310         IMAGE_LOGE("[ImageSource]get valid image status fail on create pixel map, ret:%{public}u.", errorCode);
1311         ImageEvent imageEvent;
1312         imageEvent.SetDecodeErrorMsg("[ImageSource]get valid image status fail on create pixel map, ret: "
1313                                      + std::to_string(errorCode));
1314         SetImageEventHeifParseErr(imageEvent);
1315         return nullptr;
1316     }
1317     if (ImageSystemProperties::GetSkiaEnabled()) {
1318         if (IsExtendedCodec(mainDecoder_.get())) {
1319             guard.unlock();
1320             return CreatePixelMapExtended(index, opts, errorCode);
1321         }
1322     }
1323 
1324     ImageEvent imageEvent;
1325     if (opts.desiredPixelFormat == PixelFormat::NV12 || opts.desiredPixelFormat == PixelFormat::NV21) {
1326         IMAGE_LOGE("[ImageSource] get YUV420 not support without going through CreatePixelMapExtended");
1327         imageEvent.SetDecodeErrorMsg("get YUV420 not support without going through CreatePixelMapExtended");
1328         return nullptr;
1329     }
1330     // the mainDecoder_ may be borrowed by Incremental decoding, so needs to be checked.
1331     if (InitMainDecoder() != SUCCESS) {
1332         IMAGE_LOGE("[ImageSource]image decode plugin is null.");
1333         imageEvent.SetDecodeErrorMsg("image decode plugin is null.");
1334         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
1335         return nullptr;
1336     }
1337     unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
1338     if (pixelMap == nullptr || pixelMap.get() == nullptr) {
1339         IMAGE_LOGE("[ImageSource]create the pixel map unique_ptr fail.");
1340         imageEvent.SetDecodeErrorMsg("create the pixel map unique_ptr fail.");
1341         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
1342         return nullptr;
1343     }
1344 
1345     ImagePlugin::PlImageInfo plInfo;
1346     errorCode = SetDecodeOptions(mainDecoder_, index, opts_, plInfo);
1347     SetDecodeInfoOptions(index, opts, plInfo, imageEvent);
1348     if (errorCode != SUCCESS) {
1349         IMAGE_LOGE("[ImageSource]set decode options error (index:%{public}u), ret:%{public}u.", index, errorCode);
1350         imageEvent.SetDecodeErrorMsg("set decode options error, ret:." + std::to_string(errorCode));
1351         return nullptr;
1352     }
1353 
1354     for (auto listener : decodeListeners_) {
1355         guard.unlock();
1356         listener->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
1357         guard.lock();
1358     }
1359 
1360     Size size = {
1361         .width = plInfo.size.width,
1362         .height = plInfo.size.height
1363     };
1364     PostProc::ValidCropValue(opts_.CropRect, size);
1365     errorCode = UpdatePixelMapInfo(opts_, plInfo, *(pixelMap.get()));
1366     if (errorCode != SUCCESS) {
1367         IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
1368         imageEvent.SetDecodeErrorMsg("update pixelmap info error, ret:." + std::to_string(errorCode));
1369         return nullptr;
1370     }
1371 
1372     DecodeContext context;
1373     FinalOutputStep finalOutputStep = FinalOutputStep::NO_CHANGE;
1374     context.pixelmapUniqueId_ = pixelMap->GetUniqueId();
1375     if (!useSkia) {
1376         bool hasNinePatch = mainDecoder_->HasProperty(NINE_PATCH);
1377         finalOutputStep = GetFinalOutputStep(opts_, *(pixelMap.get()), hasNinePatch);
1378         IMAGE_LOGD("[ImageSource]finalOutputStep:%{public}d. opts.allocatorType %{public}d", finalOutputStep,
1379             opts_.allocatorType);
1380 
1381         if (finalOutputStep == FinalOutputStep::NO_CHANGE) {
1382             context.allocatorType = opts_.allocatorType;
1383         } else {
1384             context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
1385         }
1386     }
1387 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1388     context.allocatorType = AllocatorType::HEAP_ALLOC;
1389 #endif
1390     errorCode = mainDecoder_->Decode(index, context);
1391     if (context.ifPartialOutput) {
1392         for (auto partialListener : decodeListeners_) {
1393             guard.unlock();
1394             partialListener->OnEvent((int)DecodeEvent::EVENT_PARTIAL_DECODE);
1395             guard.lock();
1396         }
1397     }
1398     UpdateDecodeInfoOptions(context, imageEvent);
1399     if (!useSkia) {
1400         ninePatchInfo_.ninePatch = context.ninePatchContext.ninePatch;
1401         ninePatchInfo_.patchSize = context.ninePatchContext.patchSize;
1402     }
1403     guard.unlock();
1404     if (errorCode != SUCCESS) {
1405         IMAGE_LOGE("[ImageSource]decode source fail, ret:%{public}u.", errorCode);
1406         imageEvent.SetDecodeErrorMsg("decode source fail, ret:." + std::to_string(errorCode));
1407         if (context.pixelsBuffer.buffer != nullptr) {
1408             if (context.freeFunc != nullptr) {
1409                 context.freeFunc(context.pixelsBuffer.buffer, context.pixelsBuffer.context,
1410                     context.pixelsBuffer.bufferSize);
1411             } else {
1412                 PixelMap::ReleaseMemory(context.allocatorType, context.pixelsBuffer.buffer,
1413                     context.pixelsBuffer.context, context.pixelsBuffer.bufferSize);
1414             }
1415         }
1416         return nullptr;
1417     }
1418 
1419 #ifdef IMAGE_COLORSPACE_FLAG
1420     // add graphic colorspace object to pixelMap.
1421     bool isSupportICCProfile = mainDecoder_->IsSupportICCProfile();
1422     if (isSupportICCProfile) {
1423         OHOS::ColorManager::ColorSpace grColorSpace = mainDecoder_->GetPixelMapColorSpace();
1424         pixelMap->InnerSetColorSpace(grColorSpace);
1425     }
1426 #endif
1427 
1428     pixelMap->SetPixelsAddr(context.pixelsBuffer.buffer, context.pixelsBuffer.context, context.pixelsBuffer.bufferSize,
1429         context.allocatorType, context.freeFunc);
1430     DecodeOptions procOpts;
1431     CopyOptionsToProcOpts(opts_.cropAndScaleStrategy == CropAndScaleStrategy::DEFAULT ? opts_ : opts, procOpts,
1432         *(pixelMap.get()));
1433     PostProc postProc;
1434     errorCode = postProc.DecodePostProc(procOpts, *(pixelMap.get()), finalOutputStep);
1435     bool cond = (errorCode != SUCCESS);
1436     CHECK_ERROR_RETURN_RET(cond, nullptr);
1437 
1438     if (!context.ifPartialOutput) {
1439         for (auto listener : decodeListeners_) {
1440             listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
1441         }
1442     }
1443 
1444     if (CreatExifMetadataByImageSource() == SUCCESS) {
1445         auto metadataPtr = exifMetadata_->Clone();
1446         pixelMap->SetExifMetadata(metadataPtr);
1447     }
1448 
1449     // not ext decode, dump pixelMap while decoding svg here
1450     ImageUtils::DumpPixelMapIfDumpEnabled(pixelMap, imageId_);
1451     return pixelMap;
1452 }
1453 
CreateIncrementalPixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)1454 unique_ptr<IncrementalPixelMap> ImageSource::CreateIncrementalPixelMap(uint32_t index, const DecodeOptions &opts,
1455     uint32_t &errorCode)
1456 {
1457     ImageDataStatistics imageDataStatistics("[ImageSource] CreateIncrementalPixelMap width = %d, height = %d," \
1458         "pixelformat = %d", opts.desiredSize.width, opts.desiredSize.height, opts.desiredPixelFormat);
1459     IncrementalPixelMap *incPixelMapPtr = new (std::nothrow) IncrementalPixelMap(index, opts, this);
1460     if (incPixelMapPtr == nullptr) {
1461         IMAGE_LOGE("[ImageSource]create the incremental pixel map unique_ptr fail.");
1462         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
1463         return nullptr;
1464     }
1465     errorCode = SUCCESS;
1466     return unique_ptr<IncrementalPixelMap>(incPixelMapPtr);
1467 }
1468 
PromoteDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,ImageDecodingState & state,uint8_t & decodeProgress)1469 uint32_t ImageSource::PromoteDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
1470     ImageDecodingState &state, uint8_t &decodeProgress)
1471 {
1472     state = ImageDecodingState::UNRESOLVED;
1473     decodeProgress = 0;
1474     uint32_t ret = SUCCESS;
1475     std::unique_lock<std::mutex> guard(decodingMutex_);
1476     opts_ = opts;
1477     auto imageStatusIter = GetValidImageStatus(index, ret);
1478     bool cond = (imageStatusIter == imageStatusMap_.end());
1479     CHECK_ERROR_RETURN_RET_LOG(cond,
1480         ret, "[ImageSource]get valid image status fail on promote decoding, ret:%{public}u.", ret);
1481     auto incrementalRecordIter = incDecodingMap_.find(&pixelMap);
1482     if (incrementalRecordIter == incDecodingMap_.end()) {
1483         ret = AddIncrementalContext(pixelMap, incrementalRecordIter);
1484         cond = ret != SUCCESS;
1485         CHECK_ERROR_RETURN_RET_LOG(cond,
1486             ret, "[ImageSource]failed to add context on incremental decoding, ret:%{public}u.", ret);
1487     }
1488     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::BASE_INFO_PARSED) {
1489         IMAGE_LOGD("[ImageSource]promote decode : set decode options.");
1490         ImagePlugin::PlImageInfo plInfo;
1491         ret = SetDecodeOptions(incrementalRecordIter->second.decoder, index, opts_, plInfo);
1492         if (ret != SUCCESS) {
1493             IMAGE_LOGE("[ImageSource]set decode options error (image index:%{public}u), ret:%{public}u.", index, ret);
1494             return ret;
1495         }
1496 
1497         auto iterator = decodeEventMap_.find((int)DecodeEvent::EVENT_HEADER_DECODE);
1498         if (iterator == decodeEventMap_.end()) {
1499             decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_HEADER_DECODE, 1));
1500             for (auto callback : decodeListeners_) {
1501                 guard.unlock();
1502                 callback->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
1503                 guard.lock();
1504             }
1505         }
1506         Size size = {
1507             .width = plInfo.size.width,
1508             .height = plInfo.size.height
1509         };
1510         PostProc::ValidCropValue(opts_.CropRect, size);
1511         ret = UpdatePixelMapInfo(opts_, plInfo, pixelMap);
1512         if (ret != SUCCESS) {
1513             IMAGE_LOGE("[ImageSource]update pixelmap info error (image index:%{public}u), ret:%{public}u.", index, ret);
1514             return ret;
1515         }
1516         incrementalRecordIter->second.IncrementalState = ImageDecodingState::IMAGE_DECODING;
1517     }
1518     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_DECODING) {
1519         ret = DoIncrementalDecoding(index, opts_, pixelMap, incrementalRecordIter->second);
1520         decodeProgress = incrementalRecordIter->second.decodingProgress;
1521         state = incrementalRecordIter->second.IncrementalState;
1522         if (isIncrementalCompleted_) {
1523             PostProc postProc;
1524             ret = postProc.DecodePostProc(opts_, pixelMap);
1525             if (state == ImageDecodingState::IMAGE_DECODED) {
1526                 auto iter = decodeEventMap_.find((int)DecodeEvent::EVENT_COMPLETE_DECODE);
1527                 if (iter == decodeEventMap_.end()) {
1528                     decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_COMPLETE_DECODE, 1));
1529                     for (auto listener : decodeListeners_) {
1530                         guard.unlock();
1531                         listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
1532                         guard.lock();
1533                     }
1534                 }
1535             }
1536         }
1537         return ret;
1538     }
1539 
1540     // IMAGE_ERROR or IMAGE_DECODED.
1541     state = incrementalRecordIter->second.IncrementalState;
1542     decodeProgress = incrementalRecordIter->second.decodingProgress;
1543     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_ERROR) {
1544         IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on incremental decoding.",
1545             incrementalRecordIter->second.IncrementalState);
1546         return ERR_IMAGE_DECODE_ABNORMAL;
1547     }
1548     return SUCCESS;
1549 }
1550 
DetachIncrementalDecoding(PixelMap & pixelMap)1551 void ImageSource::DetachIncrementalDecoding(PixelMap &pixelMap)
1552 {
1553     std::lock_guard<std::mutex> guard(decodingMutex_);
1554     auto iter = incDecodingMap_.find(&pixelMap);
1555     if (iter == incDecodingMap_.end()) {
1556         return;
1557     }
1558 
1559     if (mainDecoder_ == nullptr) {
1560         // return back the decoder to mainDecoder_.
1561         mainDecoder_ = std::move(iter->second.decoder);
1562         iter->second.decoder = nullptr;
1563     }
1564     incDecodingMap_.erase(iter);
1565 }
1566 
UpdateData(const uint8_t * data,uint32_t size,bool isCompleted)1567 uint32_t ImageSource::UpdateData(const uint8_t *data, uint32_t size, bool isCompleted)
1568 {
1569     bool cond = (size > MAX_SOURCE_SIZE);
1570     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_TOO_LARGE,
1571                                "%{public}s input size %{public}u is too large.",  __func__, size);
1572     ImageDataStatistics imageDataStatistics("[ImageSource]UpdateData");
1573     cond = sourceStreamPtr_ == nullptr;
1574     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1575                                "[ImageSource]image source update data, source stream is null.");
1576     std::lock_guard<std::mutex> guard(decodingMutex_);
1577     if (isCompleted) {
1578         isIncrementalCompleted_ = isCompleted;
1579     }
1580     return sourceStreamPtr_->UpdateData(data, size, isCompleted);
1581 }
1582 
GetDecodeEvent()1583 DecodeEvent ImageSource::GetDecodeEvent()
1584 {
1585     return decodeEvent_;
1586 }
SetDngImageSize(uint32_t index,ImageInfo & imageInfo)1587 void ImageSource::SetDngImageSize(uint32_t index, ImageInfo &imageInfo)
1588 {
1589     Size rawSize {0, 0};
1590     uint32_t exifWidthRet = SUCCESS;
1591     uint32_t exifHeightRet = SUCCESS;
1592     if (imageInfo.encodedFormat == IMAGE_FORMAT_RAW) {
1593         exifWidthRet = GetImagePropertyInt(index, KEY_IMAGE_WIDTH, rawSize.width);
1594         exifHeightRet = GetImagePropertyInt(index, KEY_IMAGE_HEIGHT, rawSize.height);
1595     }
1596 
1597     if (rawSize.width != 0 && rawSize.height != 0
1598         && exifWidthRet == SUCCESS && exifHeightRet == SUCCESS) {
1599         imageInfo.size.width = rawSize.width;
1600         imageInfo.size.height = rawSize.height;
1601     }
1602 }
1603 
GetImageInfo(uint32_t index,ImageInfo & imageInfo)1604 uint32_t ImageSource::GetImageInfo(uint32_t index, ImageInfo &imageInfo)
1605 {
1606     ImageTrace imageTrace("GetImageInfo by index");
1607     uint32_t ret = SUCCESS;
1608     std::unique_lock<std::mutex> guard(decodingMutex_);
1609     auto iter = GetValidImageStatus(index, ret);
1610     if (iter == imageStatusMap_.end()) {
1611         guard.unlock();
1612         IMAGE_LOGD("[ImageSource]get valid image status fail on get image info, ret:%{public}u.", ret);
1613         return ret;
1614     }
1615     ImageInfo &info = (iter->second).imageInfo;
1616     bool cond = (info.size.width == 0 || info.size.height == 0);
1617     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DECODE_FAILED,
1618                                "[ImageSource]get the image size fail on get image info, width:%{public}d,"
1619                                "height:%{public}d.", info.size.width, info.size.height);
1620     imageInfo = info;
1621     return SUCCESS;
1622 }
1623 
GetImageId()1624 uint64_t ImageSource::GetImageId()
1625 {
1626     return imageId_;
1627 }
1628 
GetImageInfoFromExif(uint32_t index,ImageInfo & imageInfo)1629 uint32_t ImageSource::GetImageInfoFromExif(uint32_t index, ImageInfo &imageInfo)
1630 {
1631     ImageTrace imageTrace("GetImageInfoFromExif by index");
1632     uint32_t ret = SUCCESS;
1633     std::unique_lock<std::mutex> guard(decodingMutex_);
1634     auto iter = GetValidImageStatus(index, ret);
1635     if (iter == imageStatusMap_.end()) {
1636         guard.unlock();
1637         IMAGE_LOGE("[ImageSource]get valid image status fail on get image info from exif, ret:%{public}u.", ret);
1638         return ret;
1639     }
1640     ImageInfo &info = (iter->second).imageInfo;
1641     bool cond = (info.size.width == 0 || info.size.height == 0);
1642     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DECODE_FAILED,
1643                                "[ImageSource]get the image size fail on get image info, width:%{public}d,"
1644                                "height:%{public}d.",
1645                                info.size.width, info.size.height);
1646     imageInfo = info;
1647     guard.unlock();
1648 
1649     SetDngImageSize(index, imageInfo);
1650     return SUCCESS;
1651 }
1652 
1653 
ModifyImageProperty(const std::string & key,const std::string & value)1654 uint32_t ImageSource::ModifyImageProperty(const std::string &key, const std::string &value)
1655 {
1656     uint32_t ret = CreatExifMetadataByImageSource(true);
1657     bool cond = (ret != SUCCESS);
1658     CHECK_DEBUG_RETURN_RET_LOG(cond, ret, "Failed to create Exif metadata "
1659                            "when attempting to modify property.");
1660     if (!exifMetadata_->SetValue(key, value)) {
1661         return ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
1662     }
1663 
1664     return SUCCESS;
1665 }
1666 
ModifyImageProperty(std::shared_ptr<MetadataAccessor> metadataAccessor,const std::string & key,const std::string & value)1667 uint32_t ImageSource::ModifyImageProperty(std::shared_ptr<MetadataAccessor> metadataAccessor,
1668     const std::string &key, const std::string &value)
1669 {
1670     if (srcFd_ != -1) {
1671         size_t fileSize = 0;
1672         if (!ImageUtils::GetFileSize(srcFd_, fileSize)) {
1673             IMAGE_LOGE("ModifyImageProperty accessor start get file size failed.");
1674         } else {
1675             IMAGE_LOGI("ModifyImageProperty accessor start fd file size:%{public}llu",
1676                 static_cast<unsigned long long>(fileSize));
1677         }
1678     }
1679     uint32_t ret = ModifyImageProperty(key, value);
1680     bool cond = (ret != SUCCESS);
1681     CHECK_ERROR_RETURN_RET_LOG(cond, ret, "Failed to create ExifMetadata.");
1682 
1683     cond = metadataAccessor == nullptr;
1684     ret = ERR_IMAGE_SOURCE_DATA;
1685     CHECK_ERROR_RETURN_RET_LOG(cond, ret,
1686                                "Failed to create image accessor when attempting to modify image property.");
1687 
1688     if (srcFd_ != -1) {
1689         size_t fileSize = 0;
1690         if (!ImageUtils::GetFileSize(srcFd_, fileSize)) {
1691             IMAGE_LOGE("ModifyImageProperty accessor end get file size failed.");
1692         } else {
1693             IMAGE_LOGI("ModifyImageProperty accessor end fd file size:%{public}llu",
1694                 static_cast<unsigned long long>(fileSize));
1695         }
1696     }
1697     metadataAccessor->Set(exifMetadata_);
1698     IMAGE_LOGI("ModifyImageProperty accesssor modify start");
1699     ret = metadataAccessor->Write();
1700     IMAGE_LOGI("ModifyImageProperty accesssor modify end");
1701     return ret;
1702 }
1703 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value)1704 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value)
1705 {
1706     std::unique_lock<std::mutex> guard(decodingMutex_);
1707     return ModifyImageProperty(key, value);
1708 }
1709 
ModifyImagePropertyEx(uint32_t index,const std::string & key,const std::string & value)1710 uint32_t ImageSource::ModifyImagePropertyEx(uint32_t index, const std::string &key, const std::string &value)
1711 {
1712     if (srcFd_ != -1) {
1713         return ModifyImageProperty(index, key, value, srcFd_);
1714     }
1715 
1716     if (!srcFilePath_.empty()) {
1717         return ModifyImageProperty(index, key, value, srcFilePath_);
1718     }
1719 
1720     if (srcBuffer_ != nullptr && srcBufferSize_ != 0) {
1721         return ModifyImageProperty(index, key, value, srcBuffer_, srcBufferSize_);
1722     }
1723     return ERROR;
1724 }
1725 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,const std::string & path)1726 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
1727     const std::string &path)
1728 {
1729     ImageDataStatistics imageDataStatistics("[ImageSource]ModifyImageProperty by path.");
1730 
1731 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1732     std::error_code ec;
1733     bool cond = (!std::filesystem::exists(path, ec));
1734     CHECK_ERROR_RETURN_RET_LOG(cond,
1735                                ERR_IMAGE_SOURCE_DATA,
1736                                "File not exists, error: %{public}d, message: %{public}s",
1737                                ec.value(), ec.message().c_str());
1738 #endif
1739 
1740     std::unique_lock<std::mutex> guard(decodingMutex_);
1741     auto metadataAccessor = MetadataAccessorFactory::Create(path);
1742     return ModifyImageProperty(metadataAccessor, key, value);
1743 }
1744 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,const int fd)1745 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
1746     const int fd)
1747 {
1748     ImageDataStatistics imageDataStatistics("[ImageSource]ModifyImageProperty by fd.");
1749     bool cond = (fd <= STDERR_FILENO);
1750     CHECK_DEBUG_RETURN_RET_LOG(cond, ERR_IMAGE_SOURCE_DATA, "Invalid file descriptor.");
1751 
1752     std::unique_lock<std::mutex> guard(decodingMutex_);
1753     size_t fileSize = 0;
1754     if (!ImageUtils::GetFileSize(fd, fileSize)) {
1755         IMAGE_LOGE("ModifyImageProperty get file size failed.");
1756     }
1757     IMAGE_LOGI("ModifyImageProperty accesssor create start, fd file size:%{public}llu",
1758         static_cast<unsigned long long>(fileSize));
1759     auto metadataAccessor = MetadataAccessorFactory::Create(fd);
1760     IMAGE_LOGI("ModifyImageProperty accesssor create end");
1761 
1762     auto ret = ModifyImageProperty(metadataAccessor, key, value);
1763     return ret;
1764 }
1765 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,uint8_t * data,uint32_t size)1766 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
1767     uint8_t *data, uint32_t size)
1768 {
1769     return ERR_MEDIA_WRITE_PARCEL_FAIL;
1770 }
1771 
PrereadSourceStream()1772 bool ImageSource::PrereadSourceStream()
1773 {
1774     uint8_t* prereadBuffer = new (std::nothrow) uint8_t[IMAGE_HEADER_SIZE];
1775     if (prereadBuffer == nullptr) {
1776         return false;
1777     }
1778     uint32_t prereadSize = 0;
1779     uint32_t savedPosition = sourceStreamPtr_->Tell();
1780     sourceStreamPtr_->Seek(0);
1781     bool retRead = sourceStreamPtr_->Read(IMAGE_HEADER_SIZE, prereadBuffer,
1782                                           IMAGE_HEADER_SIZE, prereadSize);
1783     sourceStreamPtr_->Seek(savedPosition);
1784     if (!retRead) {
1785         IMAGE_LOGE("Preread source stream failed.");
1786         delete[] prereadBuffer; // Don't forget to delete tmpBuffer if read failed
1787         return false;
1788     }
1789     delete[] prereadBuffer;
1790     return true;
1791 }
1792 
CreatExifMetadataByImageSource(bool addFlag)1793 uint32_t ImageSource::CreatExifMetadataByImageSource(bool addFlag)
1794 {
1795     IMAGE_LOGD("CreatExifMetadataByImageSource");
1796     if (exifMetadata_ != nullptr) {
1797         IMAGE_LOGD("exifMetadata_ exist return SUCCESS");
1798         return SUCCESS;
1799     }
1800 
1801     if (sourceStreamPtr_ == nullptr) {
1802         IMAGE_LOGD("sourceStreamPtr_ not exist return ERR");
1803         return ERR_IMAGE_SOURCE_DATA;
1804     }
1805 
1806     IMAGE_LOGD("sourceStreamPtr create metadataAccessor");
1807     if (!PrereadSourceStream()) {
1808         return ERR_IMAGE_SOURCE_DATA;
1809     }
1810     uint32_t bufferSize = sourceStreamPtr_->GetStreamSize();
1811     auto bufferPtr = sourceStreamPtr_->GetDataPtr();
1812     if (bufferPtr != nullptr) {
1813         uint32_t ret = CreateExifMetadata(bufferPtr, bufferSize, addFlag, true);
1814         if (ret != ERR_MEDIA_MMAP_FILE_CHANGED) {
1815             return ret;
1816         }
1817     }
1818 
1819     if (bufferSize == 0) {
1820         IMAGE_LOGE("Invalid buffer size. It's zero. Please check the buffer size.");
1821         return ERR_IMAGE_SOURCE_DATA;
1822     }
1823 
1824     if (bufferSize > MAX_SOURCE_SIZE) {
1825         IMAGE_LOGE("Invalid buffer size. It's too big. Please check the buffer size.");
1826         return ERR_IMAGE_SOURCE_DATA;
1827     }
1828     uint32_t error = SUCCESS;
1829     auto tmpBuffer = ReadSourceBuffer(bufferSize, error);
1830     if (tmpBuffer == nullptr) {
1831         return error;
1832     }
1833     uint32_t result = CreateExifMetadata(tmpBuffer, bufferSize, addFlag);
1834     if (result == ERR_MEDIA_MMAP_FILE_CHANGED) {
1835         result = ERR_IMAGE_SOURCE_DATA;
1836     }
1837     delete[] tmpBuffer; // Don't forget to delete tmpBuffer after using it
1838     return result;
1839 }
1840 
CreateExifMetadata(uint8_t * buffer,const uint32_t size,bool addFlag,bool hasOriginalFd)1841 uint32_t ImageSource::CreateExifMetadata(uint8_t *buffer, const uint32_t size, bool addFlag, bool hasOriginalFd)
1842 {
1843     uint32_t error = SUCCESS;
1844     DataInfo dataInfo {buffer, size};
1845     std::shared_ptr<MetadataAccessor> metadataAccessor;
1846     if (hasOriginalFd) {
1847         metadataAccessor = MetadataAccessorFactory::Create(dataInfo, error, BufferMetadataStream::Fix,
1848                                                            sourceStreamPtr_->GetOriginalFd(),
1849                                                            sourceStreamPtr_->GetOriginalPath());
1850     } else {
1851         metadataAccessor = MetadataAccessorFactory::Create(dataInfo, error, BufferMetadataStream::Fix);
1852     }
1853 
1854     if (metadataAccessor == nullptr) {
1855         IMAGE_LOGD("metadataAccessor nullptr return ERR");
1856         return error == ERR_MEDIA_MMAP_FILE_CHANGED ? error : ERR_IMAGE_SOURCE_DATA;
1857     }
1858 
1859     uint32_t ret = metadataAccessor->Read();
1860     if (ret != SUCCESS && !addFlag) {
1861         IMAGE_LOGD("get metadataAccessor ret %{public}d", ret);
1862         return metadataAccessor->IsFileSizeChanged() ? ERR_MEDIA_MMAP_FILE_CHANGED : ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
1863     }
1864 
1865     if (metadataAccessor->Get() == nullptr) {
1866         if (!metadataAccessor->Create()) {
1867             IMAGE_LOGD("metadataAccessor create failed.");
1868             return ERR_IMAGE_SOURCE_DATA;
1869         }
1870     }
1871 
1872     exifMetadata_ = metadataAccessor->Get();
1873     return SUCCESS;
1874 }
1875 
GetImagePropertyCommon(uint32_t index,const std::string & key,std::string & value)1876 uint32_t ImageSource::GetImagePropertyCommon(uint32_t index, const std::string &key, std::string &value)
1877 {
1878     if (isExifReadFailed_ && exifMetadata_ == nullptr) {
1879         return exifReadStatus_;
1880     }
1881     uint32_t ret = CreatExifMetadataByImageSource();
1882     if (ret != SUCCESS) {
1883         if (key.substr(0, KEY_SIZE) == "Hw") {
1884             value = DEFAULT_EXIF_VALUE;
1885             return SUCCESS;
1886         }
1887         IMAGE_LOGD("Failed to create Exif metadata "
1888             "when attempting to get property.");
1889         isExifReadFailed_ = true;
1890         exifReadStatus_ = ret;
1891         return ret;
1892     }
1893 
1894     return exifMetadata_->GetValue(key, value);
1895 }
1896 
GetImagePropertyInt(uint32_t index,const std::string & key,int32_t & value)1897 uint32_t ImageSource::GetImagePropertyInt(uint32_t index, const std::string &key, int32_t &value)
1898 {
1899     std::unique_lock<std::mutex> guard(decodingMutex_);
1900 
1901     if (key.empty()) {
1902         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
1903     }
1904     // keep aline with previous logical for delay time and disposal type
1905     if (IMAGE_DELAY_TIME.compare(key) == ZERO || IMAGE_DISPOSAL_TYPE.compare(key) == ZERO) {
1906         IMAGE_LOGD("GetImagePropertyInt special key: %{public}s", key.c_str());
1907         uint32_t ret = mainDecoder_->GetImagePropertyInt(index, key, value);
1908         return ret;
1909     }
1910     std::string strValue;
1911     uint32_t ret = GetImagePropertyCommon(index, key, strValue);
1912     if (key == "Orientation") {
1913         if (ORIENTATION_INT_MAP.count(strValue) == 0) {
1914             IMAGE_LOGD("ORIENTATION_INT_MAP not find %{public}s", strValue.c_str());
1915             return ERR_IMAGE_SOURCE_DATA;
1916         }
1917         strValue = std::to_string(ORIENTATION_INT_MAP.at(strValue));
1918     }
1919     IMAGE_LOGD("convert string to int %{public}s", strValue.c_str());
1920     std::from_chars_result res = std::from_chars(strValue.data(), strValue.data() + strValue.size(), value);
1921     if (res.ec != std::errc()) {
1922         IMAGE_LOGD("convert string to int failed");
1923         return ERR_IMAGE_SOURCE_DATA;
1924     }
1925 
1926     return ret;
1927 }
1928 
GetImagePropertyString(uint32_t index,const std::string & key,std::string & value)1929 uint32_t ImageSource::GetImagePropertyString(uint32_t index, const std::string &key, std::string &value)
1930 {
1931     if (key.empty()) {
1932         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
1933     }
1934     uint32_t ret = SUCCESS;
1935     if (IMAGE_GIFLOOPCOUNT_TYPE.compare(key) == ZERO) {
1936         IMAGE_LOGD("GetImagePropertyString special key: %{public}s", key.c_str());
1937         (void)GetFrameCount(ret);
1938         if (ret != SUCCESS || mainDecoder_ == nullptr) {
1939             IMAGE_LOGE("[ImageSource]GetFrameCount get frame sum error.");
1940             return ret;
1941         } else {
1942             ret = mainDecoder_->GetImagePropertyString(index, key, value);
1943             if (ret != SUCCESS) {
1944                 IMAGE_LOGE("[ImageSource]GetLoopCount get loop count issue. errorCode=%{public}u", ret);
1945                 return ret;
1946             }
1947         }
1948         return ret;
1949     }
1950 
1951     std::unique_lock<std::mutex> guard(decodingMutex_);
1952     std::unique_lock<std::mutex> guardFile(fileMutex_);
1953     return GetImagePropertyCommon(index, key, value);
1954 }
1955 
GetSourceInfo(uint32_t & errorCode)1956 const SourceInfo &ImageSource::GetSourceInfo(uint32_t &errorCode)
1957 {
1958     std::lock_guard<std::mutex> guard(decodingMutex_);
1959     if (IsSpecialYUV()) {
1960         return sourceInfo_;
1961     }
1962     errorCode = DecodeSourceInfo(true);
1963     return sourceInfo_;
1964 }
1965 
RegisterListener(PeerListener * listener)1966 void ImageSource::RegisterListener(PeerListener *listener)
1967 {
1968     if (listener == nullptr) {
1969         return;
1970     }
1971     std::lock_guard<std::mutex> guard(listenerMutex_);
1972     listeners_.insert(listener);
1973 }
1974 
UnRegisterListener(PeerListener * listener)1975 void ImageSource::UnRegisterListener(PeerListener *listener)
1976 {
1977     if (listener == nullptr) {
1978         return;
1979     }
1980     std::lock_guard<std::mutex> guard(listenerMutex_);
1981     auto iter = listeners_.find(listener);
1982     if (iter != listeners_.end()) {
1983         listeners_.erase(iter);
1984     }
1985 }
1986 
AddDecodeListener(DecodeListener * listener)1987 void ImageSource::AddDecodeListener(DecodeListener *listener)
1988 {
1989     if (listener == nullptr) {
1990         IMAGE_LOGE("AddDecodeListener listener null");
1991         return;
1992     }
1993     std::lock_guard<std::mutex> guard(listenerMutex_);
1994     decodeListeners_.insert(listener);
1995 }
1996 
RemoveDecodeListener(DecodeListener * listener)1997 void ImageSource::RemoveDecodeListener(DecodeListener *listener)
1998 {
1999     if (listener == nullptr) {
2000         IMAGE_LOGE("Attempted to remove a null listener "
2001             "from decode listeners.");
2002         return;
2003     }
2004     std::lock_guard<std::mutex> guard(listenerMutex_);
2005     auto iter = decodeListeners_.find(listener);
2006     if (iter != decodeListeners_.end()) {
2007         decodeListeners_.erase(iter);
2008     }
2009 }
2010 
~ImageSource()2011 ImageSource::~ImageSource() __attribute__((no_sanitize("cfi")))
2012 {
2013     IMAGE_LOGD("ImageSource destructor enter");
2014     std::lock_guard<std::mutex> guard(listenerMutex_);
2015     for (const auto &listener : listeners_) {
2016         if (listener == nullptr) {
2017             IMAGE_LOGE("Attempted to destory a null listener "
2018                 "from decode listeners.");
2019         } else {
2020             listener->OnPeerDestory();
2021         }
2022     }
2023     if (srcFd_ != -1) {
2024         close(srcFd_);
2025     }
2026 }
2027 
IsStreamCompleted()2028 bool ImageSource::IsStreamCompleted()
2029 {
2030     std::lock_guard<std::mutex> guard(decodingMutex_);
2031     return sourceStreamPtr_->IsStreamCompleted();
2032 }
2033 
ParseHdrType()2034 bool ImageSource::ParseHdrType()
2035 {
2036     std::unique_lock<std::mutex> guard(decodingMutex_);
2037     uint32_t ret = SUCCESS;
2038     auto iter = GetValidImageStatus(0, ret);
2039     if (iter == imageStatusMap_.end()) {
2040         IMAGE_LOGE("[ImageSource] IsHdrImage, get valid image status fail, ret:%{public}u.", ret);
2041         return false;
2042     }
2043     if (InitMainDecoder() != SUCCESS) {
2044         IMAGE_LOGE("[ImageSource] IsHdrImage ,get decoder failed");
2045         return false;
2046     }
2047     sourceHdrType_ = mainDecoder_->CheckHdrType();
2048     return true;
2049 }
2050 
IsHdrImage()2051 bool ImageSource::IsHdrImage()
2052 {
2053     if (sourceHdrType_ != ImageHdrType::UNKNOWN) {
2054         return sourceHdrType_ > ImageHdrType::SDR;
2055     }
2056     if (!ParseHdrType()) {
2057         return false;
2058     }
2059     return sourceHdrType_ > ImageHdrType::SDR;
2060 }
2061 
IsSingleHdrImage(ImageHdrType type)2062 bool ImageSource::IsSingleHdrImage(ImageHdrType type)
2063 {
2064     return type == ImageHdrType::HDR_VIVID_SINGLE || type == ImageHdrType::HDR_ISO_SINGLE;
2065 }
2066 
IsDualHdrImage(ImageHdrType type)2067 bool ImageSource::IsDualHdrImage(ImageHdrType type)
2068 {
2069     return type == ImageHdrType::HDR_VIVID_DUAL || type == ImageHdrType::HDR_ISO_DUAL || type == ImageHdrType::HDR_CUVA;
2070 }
2071 
GetExifMetadata()2072 NATIVEEXPORT std::shared_ptr<ExifMetadata> ImageSource::GetExifMetadata()
2073 {
2074     if (exifMetadata_ != nullptr) {
2075         return exifMetadata_;
2076     }
2077 
2078     if (SUCCESS != CreatExifMetadataByImageSource(false)) {
2079         return nullptr;
2080     }
2081 
2082     return exifMetadata_;
2083 }
2084 
SetExifMetadata(std::shared_ptr<ExifMetadata> & ptr)2085 NATIVEEXPORT void ImageSource::SetExifMetadata(std::shared_ptr<ExifMetadata> &ptr)
2086 {
2087     exifMetadata_ = ptr;
2088 }
2089 
RemoveImageProperties(uint32_t index,const std::set<std::string> & keys,const std::string & path)2090 uint32_t ImageSource::RemoveImageProperties(uint32_t index, const std::set<std::string> &keys, const std::string &path)
2091 {
2092 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
2093     if (!std::filesystem::exists(path)) {
2094         return ERR_IMAGE_SOURCE_DATA;
2095     }
2096 #endif
2097 
2098     std::unique_lock<std::mutex> guard(decodingMutex_);
2099     auto metadataAccessor = MetadataAccessorFactory::Create(path);
2100     return RemoveImageProperties(metadataAccessor, keys);
2101 }
2102 
RemoveImageProperties(uint32_t index,const std::set<std::string> & keys,const int fd)2103 uint32_t ImageSource::RemoveImageProperties(uint32_t index, const std::set<std::string> &keys, const int fd)
2104 {
2105     if (fd <= STDERR_FILENO) {
2106         return ERR_IMAGE_SOURCE_DATA;
2107     }
2108 
2109     std::unique_lock<std::mutex> guard(decodingMutex_);
2110     auto metadataAccessor = MetadataAccessorFactory::Create(fd);
2111     return RemoveImageProperties(metadataAccessor, keys);
2112 }
2113 
RemoveImageProperties(uint32_t index,const std::set<std::string> & keys,uint8_t * data,uint32_t size)2114 uint32_t ImageSource::RemoveImageProperties(uint32_t index, const std::set<std::string> &keys,
2115                                             uint8_t *data, uint32_t size)
2116 {
2117     return ERR_MEDIA_WRITE_PARCEL_FAIL;
2118 }
2119 
2120 // ------------------------------- private method -------------------------------
ImageSource(unique_ptr<SourceStream> && stream,const SourceOptions & opts)2121 ImageSource::ImageSource(unique_ptr<SourceStream> &&stream, const SourceOptions &opts)
2122     : sourceStreamPtr_(stream.release())
2123 {
2124     sourceInfo_.baseDensity = opts.baseDensity;
2125     sourceOptions_.baseDensity = opts.baseDensity;
2126     sourceOptions_.pixelFormat = opts.pixelFormat;
2127     sourceOptions_.size.width = opts.size.width;
2128     sourceOptions_.size.height = opts.size.height;
2129 
2130     // use format hint in svg format for the performance purpose
2131     if (opts.formatHint == InnerFormat::SVG_FORMAT) {
2132         sourceInfo_.encodedFormat = opts.formatHint;
2133         sourceOptions_.formatHint = opts.formatHint;
2134     }
2135     imageId_ = GetNowTimeMicroSeconds();
2136     sourceHdrType_ = ImageHdrType::UNKNOWN;
2137 }
2138 
InitClass()2139 ImageSource::FormatAgentMap ImageSource::InitClass()
2140 {
2141     vector<ClassInfo> classInfos;
2142     pluginServer_.PluginServerGetClassInfo<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, classInfos);
2143     set<string> formats;
2144     for (auto &info : classInfos) {
2145         auto &capabilities = info.capabilities;
2146         auto iter = capabilities.find(IMAGE_ENCODE_FORMAT);
2147         if (iter == capabilities.end()) {
2148             continue;
2149         }
2150 
2151         AttrData &attr = iter->second;
2152         string format;
2153         if (SUCCESS != attr.GetValue(format)) {
2154             IMAGE_LOGE("[ImageSource]attr data get format:[%{public}s] failed.", format.c_str());
2155             continue;
2156         }
2157         formats.insert(move(format));
2158     }
2159 
2160     FormatAgentMap tempAgentMap;
2161     AbsImageFormatAgent *formatAgent = nullptr;
2162     for (auto format : formats) {
2163         map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(format) } };
2164         formatAgent =
2165             pluginServer_.CreateObject<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, capabilities);
2166         if (formatAgent == nullptr) {
2167             continue;
2168         }
2169         tempAgentMap.insert(FormatAgentMap::value_type(std::move(format), formatAgent));
2170     }
2171     return tempAgentMap;
2172 }
2173 
CheckEncodedFormat(AbsImageFormatAgent & agent)2174 uint32_t ImageSource::CheckEncodedFormat(AbsImageFormatAgent &agent)
2175 {
2176     uint32_t size = agent.GetHeaderSize();
2177     ImagePlugin::DataStreamBuffer outData;
2178     uint32_t res = GetData(outData, size);
2179     if (res != SUCCESS) {
2180         return res;
2181     }
2182     if (!agent.CheckFormat(outData.inputStreamBuffer, size)) {
2183         IMAGE_LOGD("[ImageSource]check mismatched format :%{public}s.", agent.GetFormatType().c_str());
2184         return ERR_IMAGE_MISMATCHED_FORMAT;
2185     }
2186     return SUCCESS;
2187 }
2188 
GetData(ImagePlugin::DataStreamBuffer & outData,size_t size)2189 uint32_t ImageSource::GetData(ImagePlugin::DataStreamBuffer &outData, size_t size) __attribute__((no_sanitize("cfi")))
2190 {
2191     std::unique_lock<std::mutex> guard(fileMutex_);
2192     if (sourceStreamPtr_ == nullptr) {
2193         IMAGE_LOGE("[ImageSource]check image format, source stream is null.");
2194         return ERR_IMAGE_INVALID_PARAMETER;
2195     }
2196     if (!sourceStreamPtr_->Peek(size, outData)) {
2197         IMAGE_LOGE("[ImageSource]stream peek the data fail, imageId %{public}" PRIu64 ", desiredSize:%{public}zu",
2198             imageId_, size);
2199         return ERR_IMAGE_SOURCE_DATA;
2200     }
2201     if (outData.inputStreamBuffer == nullptr || outData.dataSize < size) {
2202         IMAGE_LOGE("[ImageSource]the outData is incomplete.");
2203         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
2204     }
2205     return SUCCESS;
2206 }
2207 
CheckFormatHint(const string & formatHint,FormatAgentMap::iterator & formatIter)2208 uint32_t ImageSource::CheckFormatHint(const string &formatHint, FormatAgentMap::iterator &formatIter)
2209 {
2210     uint32_t ret = ERROR;
2211     formatIter = formatAgentMap_.find(formatHint);
2212     if (formatIter == formatAgentMap_.end()) {
2213         IMAGE_LOGE("[ImageSource]check input format fail.");
2214         return ret;
2215     }
2216     AbsImageFormatAgent *agent = formatIter->second;
2217     ret = CheckEncodedFormat(*agent);
2218     if (ret != SUCCESS) {
2219         if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
2220             IMAGE_LOGE("[ImageSource]image source incomplete.");
2221         }
2222         return ret;
2223     }
2224     return SUCCESS;
2225 }
2226 
DoCreateDecoder(std::string codecFormat,PluginServer & pluginServer,InputDataStream & sourceData,uint32_t & errorCode)2227 AbsImageDecoder *DoCreateDecoder(std::string codecFormat, PluginServer &pluginServer, InputDataStream &sourceData,
2228     uint32_t &errorCode) __attribute__((no_sanitize("cfi")))
2229 {
2230     map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(codecFormat) } };
2231     for (const auto &capability : capabilities) {
2232         std::string x = "undefined";
2233         capability.second.GetValue(x);
2234         IMAGE_LOGD("[ImageSource] capabilities [%{public}s],[%{public}s]", capability.first.c_str(), x.c_str());
2235     }
2236     auto decoder = pluginServer.CreateObject<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT, capabilities);
2237     if (decoder == nullptr) {
2238         IMAGE_LOGE("[ImageSource]failed to create decoder object.");
2239         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
2240         return nullptr;
2241     }
2242     errorCode = SUCCESS;
2243     decoder->SetSource(sourceData);
2244     return decoder;
2245 }
2246 
GetFormatExtended(string & format)2247 uint32_t ImageSource::GetFormatExtended(string &format) __attribute__((no_sanitize("cfi")))
2248 {
2249     if (mainDecoder_ != nullptr) {
2250         format = sourceInfo_.encodedFormat;
2251         return SUCCESS;
2252     }
2253 
2254     if (sourceStreamPtr_ == nullptr) {
2255         IMAGE_LOGE("Source stream pointer is null.");
2256         return ERR_MEDIA_NULL_POINTER;
2257     }
2258 
2259     auto imageType = sourceStreamPtr_->Tell();
2260     uint32_t errorCode = ERR_IMAGE_DECODE_ABNORMAL;
2261     auto codec = DoCreateDecoder(InnerFormat::IMAGE_EXTENDED_CODEC, pluginServer_, *sourceStreamPtr_, errorCode);
2262     if (errorCode != SUCCESS || codec == nullptr) {
2263         IMAGE_LOGE("No extended decoder available.");
2264         return errorCode;
2265     }
2266     const static string EXT_ENCODED_FORMAT_KEY = "EncodedFormat";
2267     auto decoderPtr = unique_ptr<AbsImageDecoder>(codec);
2268     if (decoderPtr == nullptr) {
2269         IMAGE_LOGE("Decoder pointer is null.");
2270         return ERR_MEDIA_NULL_POINTER;
2271     }
2272     ProgDecodeContext context;
2273     if (IsIncrementalSource() &&
2274         decoderPtr->PromoteIncrementalDecode(UINT32_MAX, context) == ERR_IMAGE_DATA_UNSUPPORT) {
2275         return ERR_IMAGE_DATA_UNSUPPORT;
2276     }
2277     errorCode = decoderPtr->GetImagePropertyString(FIRST_FRAME, EXT_ENCODED_FORMAT_KEY, format);
2278     if (errorCode != SUCCESS) {
2279         if (decoderPtr->GetHeifParseErr() != 0) {
2280             heifParseErr_ = decoderPtr->GetHeifParseErr();
2281         }
2282         IMAGE_LOGD("Failed to get extended format. Error code: %{public}d.", errorCode);
2283         return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
2284     }
2285 
2286     if (!ImageSystemProperties::GetSkiaEnabled()) {
2287         IMAGE_LOGD("Extended SK decode is closed.");
2288         if (format != "image/gif") {
2289             sourceStreamPtr_->Seek(imageType);
2290             return ERR_MEDIA_DATA_UNSUPPORT;
2291         }
2292     }
2293     mainDecoder_ = std::move(decoderPtr);
2294     if (mainDecoder_ == nullptr) {
2295         IMAGE_LOGE("MainDecoder is null. errno:%{public}d", errno);
2296         return ERR_MEDIA_NULL_POINTER;
2297     }
2298     return errorCode;
2299 }
2300 
GetEncodedFormat(const string & formatHint,string & format)2301 uint32_t ImageSource::GetEncodedFormat(const string &formatHint, string &format)
2302 {
2303     uint32_t ret;
2304     auto hintIter = formatAgentMap_.end();
2305     if (!formatHint.empty()) {
2306         ret = CheckFormatHint(formatHint, hintIter);
2307         if (ret == SUCCESS) {
2308             format = hintIter->first;
2309             IMAGE_LOGD("[ImageSource]check input image format success, format:%{public}s.", format.c_str());
2310             return SUCCESS;
2311         } else {
2312             IMAGE_LOGE("[ImageSource]checkFormatHint error, type: %{public}d", ret);
2313             return ret;
2314         }
2315     }
2316 
2317     if (GetFormatExtended(format) == SUCCESS) {
2318         return SUCCESS;
2319     }
2320 
2321     for (auto iter = formatAgentMap_.begin(); iter != formatAgentMap_.end(); ++iter) {
2322         string curFormat = iter->first;
2323         if (iter == hintIter || curFormat == InnerFormat::RAW_FORMAT) {
2324             continue; // has been checked before.
2325         }
2326         AbsImageFormatAgent *agent = iter->second;
2327         ret = CheckEncodedFormat(*agent);
2328         if (ret == ERR_IMAGE_MISMATCHED_FORMAT) {
2329             continue;
2330         } else if (ret == SUCCESS) {
2331             IMAGE_LOGD("[ImageSource]GetEncodedFormat success format :%{public}s.", iter->first.c_str());
2332             format = iter->first;
2333             return SUCCESS;
2334         } else {
2335             IMAGE_LOGD("[ImageSource]checkEncodedFormat error, type: %{public}d", ret);
2336             return ret;
2337         }
2338     }
2339 
2340     // default return raw image, ERR_IMAGE_MISMATCHED_FORMAT case
2341     format = InnerFormat::RAW_FORMAT;
2342     IMAGE_LOGI("[ImageSource]image default to raw format.");
2343     return SUCCESS;
2344 }
2345 
OnSourceRecognized(bool isAcquiredImageNum)2346 uint32_t ImageSource::OnSourceRecognized(bool isAcquiredImageNum) __attribute__((no_sanitize("cfi")))
2347 {
2348     uint32_t ret = InitMainDecoder();
2349     if (ret != SUCCESS) {
2350         sourceInfo_.state = SourceInfoState::UNSUPPORTED_FORMAT;
2351         decodeState_ = SourceDecodingState::UNSUPPORTED_FORMAT;
2352         IMAGE_LOGE("[ImageSource]image decode error, ret:[%{public}u].", ret);
2353         return ret;
2354     }
2355 
2356     // for raw image, we need check the original format after decoder initialzation
2357     string value;
2358     ret = mainDecoder_->GetImagePropertyString(FIRST_FRAME, ACTUAL_IMAGE_ENCODED_FORMAT, value);
2359     if (ret == SUCCESS) {
2360         // update new format
2361         sourceInfo_.encodedFormat = value;
2362         IMAGE_LOGI("[ImageSource] update new format, value:%{public}s", value.c_str());
2363     }
2364 
2365     if (isAcquiredImageNum) {
2366         ret = mainDecoder_->GetTopLevelImageNum(sourceInfo_.topLevelImageNum);
2367         if (ret != SUCCESS) {
2368             if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
2369                 sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
2370                 IMAGE_LOGE("[ImageSource]image source data incomplete.");
2371                 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
2372             }
2373             sourceInfo_.state = SourceInfoState::FILE_INFO_ERROR;
2374             decodeState_ = SourceDecodingState::FILE_INFO_ERROR;
2375             IMAGE_LOGD("[ImageSource]OnSourceRecognized image source error.");
2376             return ret;
2377         }
2378     }
2379     sourceInfo_.state = SourceInfoState::FILE_INFO_PARSED;
2380     decodeState_ = SourceDecodingState::FILE_INFO_DECODED;
2381     return SUCCESS;
2382 }
2383 
OnSourceUnresolved()2384 uint32_t ImageSource::OnSourceUnresolved()
2385 {
2386     string formatResult;
2387     if (!isAstc_.has_value()) {
2388         ImagePlugin::DataStreamBuffer outData;
2389         uint32_t res = GetData(outData, ASTC_HEADER_SIZE);
2390         if (res == SUCCESS) {
2391             isAstc_ = IsASTC(outData.inputStreamBuffer, outData.dataSize);
2392         }
2393     }
2394     if (isAstc_.has_value() && isAstc_.value()) {
2395         formatResult = InnerFormat::ASTC_FORMAT;
2396     } else {
2397         auto ret = GetEncodedFormat(sourceInfo_.encodedFormat, formatResult);
2398         if (ret != SUCCESS) {
2399             if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
2400                 IMAGE_LOGE("[ImageSource]image source incomplete.");
2401                 sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
2402                 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
2403             } else if (ret == ERR_IMAGE_UNKNOWN_FORMAT) {
2404                 IMAGE_LOGE("[ImageSource]image unknown format.");
2405                 sourceInfo_.state = SourceInfoState::UNKNOWN_FORMAT;
2406                 decodeState_ = SourceDecodingState::UNKNOWN_FORMAT;
2407                 return ERR_IMAGE_UNKNOWN_FORMAT;
2408             }
2409             sourceInfo_.state = SourceInfoState::SOURCE_ERROR;
2410             decodeState_ = SourceDecodingState::SOURCE_ERROR;
2411             IMAGE_LOGD("[ImageSource]OnSourceUnresolved image source error.");
2412             return ret;
2413         }
2414     }
2415     sourceInfo_.encodedFormat = formatResult;
2416     decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
2417     return SUCCESS;
2418 }
2419 
GetSourceDecodingState(SourceDecodingState decodeState_)2420 uint32_t GetSourceDecodingState(SourceDecodingState decodeState_)
2421 {
2422     uint32_t ret = SUCCESS;
2423     switch (decodeState_) {
2424         case SourceDecodingState::SOURCE_ERROR: {
2425             ret = ERR_IMAGE_SOURCE_DATA;
2426             IMAGE_LOGD("[ImageSource]source error.");
2427             break;
2428         }
2429         case SourceDecodingState::UNKNOWN_FORMAT: {
2430             ret = ERR_IMAGE_UNKNOWN_FORMAT;
2431             break;
2432         }
2433         case SourceDecodingState::UNSUPPORTED_FORMAT: {
2434             ret = ERR_IMAGE_PLUGIN_CREATE_FAILED;
2435             break;
2436         }
2437         case SourceDecodingState::FILE_INFO_ERROR: {
2438             ret = ERR_IMAGE_DECODE_FAILED;
2439             break;
2440         }
2441         default: {
2442             ret = ERROR;
2443             break;
2444         }
2445     }
2446     return ret;
2447 }
2448 
DecodeSourceInfo(bool isAcquiredImageNum)2449 uint32_t ImageSource::DecodeSourceInfo(bool isAcquiredImageNum)
2450 {
2451     uint32_t ret = SUCCESS;
2452     if (decodeState_ >= SourceDecodingState::FILE_INFO_DECODED) {
2453         if (isAcquiredImageNum) {
2454             decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
2455         } else {
2456             return SUCCESS;
2457         }
2458     }
2459     if (decodeState_ == SourceDecodingState::UNRESOLVED) {
2460         ret = OnSourceUnresolved();
2461         if (ret != SUCCESS) {
2462             IMAGE_LOGD("[ImageSource]unresolved source: check format failed, ret:[%{public}d].", ret);
2463             return ret;
2464         }
2465     }
2466     if (decodeState_ == SourceDecodingState::FORMAT_RECOGNIZED) {
2467         if (sourceInfo_.encodedFormat == InnerFormat::ASTC_FORMAT) {
2468             sourceInfo_.state = SourceInfoState::FILE_INFO_PARSED;
2469             decodeState_ = SourceDecodingState::FILE_INFO_DECODED;
2470         } else {
2471             ret = OnSourceRecognized(isAcquiredImageNum);
2472             if (ret != SUCCESS) {
2473                 IMAGE_LOGE("[ImageSource]recognized source: get source info failed, ret:[%{public}d].", ret);
2474                 return ret;
2475             }
2476         }
2477         return SUCCESS;
2478     }
2479     IMAGE_LOGE("[ImageSource]invalid source state %{public}d on decode source info.", decodeState_);
2480     ret = GetSourceDecodingState(decodeState_);
2481     return ret;
2482 }
2483 
DecodeImageInfo(uint32_t index,ImageStatusMap::iterator & iter)2484 uint32_t ImageSource::DecodeImageInfo(uint32_t index, ImageStatusMap::iterator &iter)
2485 {
2486     uint32_t ret = DecodeSourceInfo(false);
2487     if (ret != SUCCESS) {
2488         IMAGE_LOGD("[ImageSource]decode the image fail, ret:%{public}d.", ret);
2489         return ret;
2490     }
2491     if (sourceInfo_.encodedFormat == InnerFormat::ASTC_FORMAT) {
2492         ASTCInfo astcInfo;
2493         if (GetASTCInfo(sourceStreamPtr_->GetDataPtr(), sourceStreamPtr_->GetStreamSize(), astcInfo)) {
2494             ImageDecodingStatus imageStatus;
2495             imageStatus.imageInfo.size = astcInfo.size;
2496             imageStatus.imageInfo.encodedFormat = sourceInfo_.encodedFormat;
2497             imageStatus.imageState = ImageDecodingState::BASE_INFO_PARSED;
2498             auto result = imageStatusMap_.insert(ImageStatusMap::value_type(index, imageStatus));
2499             iter = result.first;
2500             return SUCCESS;
2501         } else {
2502             IMAGE_LOGE("[ImageSource] decode astc image info failed.");
2503             return ERR_IMAGE_DECODE_FAILED;
2504         }
2505     }
2506     if (mainDecoder_ == nullptr) {
2507         IMAGE_LOGE("[ImageSource]get image size, image decode plugin is null.");
2508         return ERR_IMAGE_PLUGIN_CREATE_FAILED;
2509     }
2510     Size size;
2511     ret = mainDecoder_->GetImageSize(index, size);
2512     if (ret == SUCCESS) {
2513         ImageDecodingStatus imageStatus;
2514         imageStatus.imageInfo.size.width = size.width;
2515         imageStatus.imageInfo.size.height = size.height;
2516         imageStatus.imageInfo.encodedFormat = sourceInfo_.encodedFormat;
2517         imageStatus.imageState = ImageDecodingState::BASE_INFO_PARSED;
2518         auto result = imageStatusMap_.insert(ImageStatusMap::value_type(index, imageStatus));
2519         iter = result.first;
2520         return SUCCESS;
2521     } else if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
2522         IMAGE_LOGE("[ImageSource]source data incomplete.");
2523         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
2524     } else {
2525         ImageDecodingStatus status;
2526         status.imageState = ImageDecodingState::BASE_INFO_ERROR;
2527         status.imageInfo.encodedFormat = "none";
2528         auto errorResult = imageStatusMap_.insert(ImageStatusMap::value_type(index, status));
2529         iter = errorResult.first;
2530         IMAGE_LOGE("[ImageSource]decode the image info fail.");
2531         return ERR_IMAGE_DECODE_FAILED;
2532     }
2533 }
2534 
InitMainDecoder()2535 uint32_t ImageSource::InitMainDecoder()
2536 {
2537     if (mainDecoder_ != nullptr) {
2538         return SUCCESS;
2539     }
2540     uint32_t result = SUCCESS;
2541     mainDecoder_ = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(result));
2542     return result;
2543 }
2544 
CreateDecoder(uint32_t & errorCode)2545 AbsImageDecoder *ImageSource::CreateDecoder(uint32_t &errorCode)
2546 {
2547     // in normal mode, we can get actual encoded format to the user
2548     // but we need transfer to skia codec for adaption, "image/x-skia"
2549     std::string encodedFormat = sourceInfo_.encodedFormat;
2550     if (opts_.sampleSize != 1) {
2551         encodedFormat = InnerFormat::EXTENDED_FORMAT;
2552     }
2553     return DoCreateDecoder(encodedFormat, pluginServer_, *sourceStreamPtr_, errorCode);
2554 }
2555 
SetDecodeOptions(std::unique_ptr<AbsImageDecoder> & decoder,uint32_t index,const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo)2556 uint32_t ImageSource::SetDecodeOptions(std::unique_ptr<AbsImageDecoder> &decoder, uint32_t index,
2557     const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo)
2558 {
2559     PixelDecodeOptions plOptions;
2560     CopyOptionsToPlugin(opts, plOptions);
2561     if (opts.desiredPixelFormat == PixelFormat::UNKNOWN) {
2562         plOptions.desiredPixelFormat = ((preference_ == MemoryUsagePreference::LOW_RAM) ? PixelFormat::RGB_565 : PixelFormat::RGBA_8888);
2563     } else {
2564         plOptions.desiredPixelFormat = opts.desiredPixelFormat;
2565     }
2566 
2567     if ((opts.desiredDynamicRange == DecodeDynamicRange::AUTO && (sourceHdrType_ > ImageHdrType::SDR)) ||
2568          opts.desiredDynamicRange == DecodeDynamicRange::HDR) {
2569         plOptions.desiredPixelFormat = PixelFormat::RGBA_8888;
2570     }
2571     if (decoder == nullptr) {
2572         IMAGE_LOGE("decoder is nullptr");
2573         return ERROR;
2574     }
2575 
2576     bool isDecodeHdrImage = (opts.desiredDynamicRange == DecodeDynamicRange::AUTO &&
2577                             (sourceHdrType_ > ImageHdrType::SDR)) ||
2578                             opts.desiredDynamicRange == DecodeDynamicRange::HDR;
2579     bool isVpeSupport10BitOutputFormat = (opts.photoDesiredPixelFormat == PixelFormat::YCBCR_P010 ||
2580                                           opts.photoDesiredPixelFormat == PixelFormat::RGBA_1010102);
2581     if (opts.photoDesiredPixelFormat != PixelFormat::UNKNOWN) {
2582         if ((isDecodeHdrImage && !isVpeSupport10BitOutputFormat) ||
2583         (!isDecodeHdrImage && isVpeSupport10BitOutputFormat)) {
2584             IMAGE_LOGE("Photos provided a error parameter");
2585             return COMMON_ERR_INVALID_PARAMETER;
2586         }
2587         plOptions.desiredPixelFormat = opts.photoDesiredPixelFormat;
2588     }
2589 
2590     uint32_t ret = decoder->SetDecodeOptions(index, plOptions, plInfo);
2591     if (ret != SUCCESS) {
2592         IMAGE_LOGE("[ImageSource]decoder plugin set decode options fail (image index:%{public}u),"
2593             "ret:%{public}u.",
2594             index, ret);
2595         return ret;
2596     }
2597     auto iter = imageStatusMap_.find(index);
2598     if (iter != imageStatusMap_.end()) {
2599         ImageInfo &info = (iter->second).imageInfo;
2600         IMAGE_LOGD("[ImageSource]SetDecodeOptions plInfo.pixelFormat %{public}d", plInfo.pixelFormat);
2601 
2602         info.pixelFormat = plInfo.pixelFormat;
2603         IMAGE_LOGD("[ImageSource]SetDecodeOptions info.pixelFormat %{public}d", info.pixelFormat);
2604     }
2605     return SUCCESS;
2606 }
2607 
UpdatePixelMapInfo(const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo,PixelMap & pixelMap)2608 uint32_t ImageSource::UpdatePixelMapInfo(const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo,
2609     PixelMap &pixelMap)
2610 {
2611     return UpdatePixelMapInfo(opts, plInfo, pixelMap, INT_ZERO);
2612 }
UpdatePixelMapInfo(const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo,PixelMap & pixelMap,int32_t fitDensity,bool isReUsed)2613 uint32_t ImageSource::UpdatePixelMapInfo(const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo,
2614     PixelMap &pixelMap, int32_t fitDensity, bool isReUsed)
2615 {
2616     pixelMap.SetEditable(opts.editable);
2617 
2618     ImageInfo info;
2619     info.baseDensity = sourceInfo_.baseDensity;
2620     if (fitDensity != INT_ZERO) {
2621         info.baseDensity = fitDensity;
2622     }
2623     info.size.width = plInfo.size.width;
2624     info.size.height = plInfo.size.height;
2625     info.pixelFormat = static_cast<PixelFormat>(plInfo.pixelFormat);
2626     info.alphaType = static_cast<AlphaType>(plInfo.alphaType);
2627     info.encodedFormat = sourceInfo_.encodedFormat;
2628 
2629     if (IsYuvFormat(info.pixelFormat)) {
2630         YUVDataInfo yuvInfo;
2631         CopyYuvInfo(yuvInfo, plInfo);
2632         pixelMap.SetImageYUVInfo(yuvInfo);
2633     }
2634 
2635     return pixelMap.SetImageInfo(info, isReUsed);
2636 }
2637 
CopyOptionsToPlugin(const DecodeOptions & opts,PixelDecodeOptions & plOpts)2638 void ImageSource::CopyOptionsToPlugin(const DecodeOptions &opts, PixelDecodeOptions &plOpts)
2639 {
2640     plOpts.CropRect.left = opts.CropRect.left;
2641     plOpts.CropRect.top = opts.CropRect.top;
2642     plOpts.CropRect.width = opts.CropRect.width;
2643     plOpts.CropRect.height = opts.CropRect.height;
2644     plOpts.desiredSize.width = opts.desiredSize.width;
2645     plOpts.desiredSize.height = opts.desiredSize.height;
2646     plOpts.rotateDegrees = opts.rotateDegrees;
2647     plOpts.sampleSize = opts.sampleSize;
2648     plOpts.desiredPixelFormat = opts.desiredPixelFormat;
2649     plOpts.desiredColorSpace = opts.desiredColorSpace;
2650     plOpts.allowPartialImage = opts.allowPartialImage;
2651     plOpts.editable = opts.editable;
2652     if (opts.SVGOpts.fillColor.isValidColor) {
2653         plOpts.plFillColor.isValidColor = opts.SVGOpts.fillColor.isValidColor;
2654         plOpts.plFillColor.color = opts.SVGOpts.fillColor.color;
2655     }
2656     if (opts.SVGOpts.strokeColor.isValidColor) {
2657         plOpts.plStrokeColor.isValidColor = opts.SVGOpts.strokeColor.isValidColor;
2658         plOpts.plStrokeColor.color = opts.SVGOpts.strokeColor.color;
2659     }
2660     if (opts.SVGOpts.SVGResize.isValidPercentage) {
2661         plOpts.plSVGResize.isValidPercentage = opts.SVGOpts.SVGResize.isValidPercentage;
2662         plOpts.plSVGResize.resizePercentage = opts.SVGOpts.SVGResize.resizePercentage;
2663     }
2664     plOpts.plDesiredColorSpace = opts.desiredColorSpaceInfo;
2665     plOpts.plReusePixelmap = opts.reusePixelmap;
2666     plOpts.cropAndScaleStrategy = opts.cropAndScaleStrategy;
2667 }
2668 
CopyOptionsToProcOpts(const DecodeOptions & opts,DecodeOptions & procOpts,PixelMap & pixelMap)2669 void ImageSource::CopyOptionsToProcOpts(const DecodeOptions &opts, DecodeOptions &procOpts, PixelMap &pixelMap)
2670 {
2671     procOpts.fitDensity = opts.fitDensity;
2672     procOpts.CropRect.left = opts.CropRect.left;
2673     procOpts.CropRect.top = opts.CropRect.top;
2674     procOpts.CropRect.width = opts.CropRect.width;
2675     procOpts.CropRect.height = opts.CropRect.height;
2676     procOpts.desiredSize.width = opts.desiredSize.width;
2677     procOpts.desiredSize.height = opts.desiredSize.height;
2678     procOpts.rotateDegrees = opts.rotateDegrees;
2679     procOpts.sampleSize = opts.sampleSize;
2680     procOpts.desiredPixelFormat = opts.desiredPixelFormat;
2681     if (opts.allocatorType == AllocatorType::DEFAULT) {
2682         procOpts.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
2683     } else {
2684         procOpts.allocatorType = opts.allocatorType;
2685     }
2686     procOpts.desiredColorSpace = opts.desiredColorSpace;
2687     procOpts.allowPartialImage = opts.allowPartialImage;
2688     procOpts.editable = opts.editable;
2689     // we need preference_ when post processing
2690     procOpts.preference = preference_;
2691     procOpts.cropAndScaleStrategy = opts.cropAndScaleStrategy;
2692 }
2693 
GetValidImageStatus(uint32_t index,uint32_t & errorCode)2694 ImageSource::ImageStatusMap::iterator ImageSource::GetValidImageStatus(uint32_t index, uint32_t &errorCode)
2695 {
2696     auto iter = imageStatusMap_.find(index);
2697     if (iter == imageStatusMap_.end()) {
2698         errorCode = DecodeImageInfo(index, iter);
2699         if (errorCode != SUCCESS) {
2700             IMAGE_LOGD("[ImageSource]image info decode fail, ret:%{public}u.", errorCode);
2701             return imageStatusMap_.end();
2702         }
2703     } else if (iter->second.imageState < ImageDecodingState::BASE_INFO_PARSED) {
2704         IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on get image status.", iter->second.imageState);
2705         errorCode = ERR_IMAGE_DECODE_FAILED;
2706         return imageStatusMap_.end();
2707     }
2708     errorCode = SUCCESS;
2709     return iter;
2710 }
2711 
AddIncrementalContext(PixelMap & pixelMap,IncrementalRecordMap::iterator & iterator)2712 uint32_t ImageSource::AddIncrementalContext(PixelMap &pixelMap, IncrementalRecordMap::iterator &iterator)
2713 {
2714     uint32_t ret = SUCCESS;
2715     IncrementalDecodingContext context;
2716     if (mainDecoder_ != nullptr) {
2717         // borrowed decoder from the mainDecoder_.
2718         context.decoder = std::move(mainDecoder_);
2719         IMAGE_LOGI("[ImageSource]mainDecoder move to context.");
2720     } else {
2721         context.decoder = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(ret));
2722     }
2723     if (context.decoder == nullptr) {
2724         IMAGE_LOGE("[ImageSource]failed to create decoder on add incremental context, ret:%{public}u.", ret);
2725         return ret;
2726     }
2727     // mainDecoder has parsed base info in DecodeImageInfo();
2728     context.IncrementalState = ImageDecodingState::BASE_INFO_PARSED;
2729     auto result = incDecodingMap_.insert(IncrementalRecordMap::value_type(&pixelMap, std::move(context)));
2730     iterator = result.first;
2731     return SUCCESS;
2732 }
2733 
DoIncrementalDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,IncrementalDecodingContext & recordContext)2734 uint32_t ImageSource::DoIncrementalDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
2735     IncrementalDecodingContext &recordContext)
2736 {
2737     IMAGE_LOGD("[ImageSource]do incremental decoding: begin.");
2738     ImageEvent imageEvent;
2739     imageEvent.SetIncrementalDecode();
2740     uint8_t *pixelAddr = static_cast<uint8_t *>(pixelMap.GetWritablePixels());
2741     ProgDecodeContext context;
2742     context.decodeContext.pixelsBuffer.buffer = pixelAddr;
2743     uint32_t ret = recordContext.decoder->PromoteIncrementalDecode(index, context);
2744     if (context.decodeContext.pixelsBuffer.buffer != nullptr && pixelAddr == nullptr) {
2745         pixelMap.SetPixelsAddr(context.decodeContext.pixelsBuffer.buffer, context.decodeContext.pixelsBuffer.context,
2746             context.decodeContext.pixelsBuffer.bufferSize, context.decodeContext.allocatorType,
2747             context.decodeContext.freeFunc);
2748     }
2749     IMAGE_LOGD("[ImageSource]do incremental decoding progress:%{public}u.", context.totalProcessProgress);
2750     recordContext.decodingProgress = context.totalProcessProgress;
2751     if (ret != SUCCESS && ret != ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
2752         recordContext.IncrementalState = ImageDecodingState::IMAGE_ERROR;
2753         IMAGE_LOGE("[ImageSource]do incremental decoding source fail, ret:%{public}u.", ret);
2754         imageEvent.SetDecodeErrorMsg("do incremental decoding source fail, ret:" + std::to_string(ret));
2755         return ret;
2756     }
2757     if (ret == SUCCESS) {
2758         recordContext.IncrementalState = ImageDecodingState::IMAGE_DECODED;
2759         IMAGE_LOGD("[ImageSource]do incremental decoding success.");
2760     }
2761     return ret;
2762 }
2763 
GetNinePatchInfo() const2764 const NinePatchInfo &ImageSource::GetNinePatchInfo() const
2765 {
2766     return ninePatchInfo_;
2767 }
2768 
SetMemoryUsagePreference(const MemoryUsagePreference preference)2769 void ImageSource::SetMemoryUsagePreference(const MemoryUsagePreference preference)
2770 {
2771     preference_ = preference;
2772 }
2773 
GetMemoryUsagePreference()2774 MemoryUsagePreference ImageSource::GetMemoryUsagePreference()
2775 {
2776     return preference_;
2777 }
2778 
GetFilterArea(const int & privacyType,std::vector<std::pair<uint32_t,uint32_t>> & ranges)2779 uint32_t ImageSource::GetFilterArea(const int &privacyType, std::vector<std::pair<uint32_t, uint32_t>> &ranges)
2780 {
2781     std::unique_lock<std::mutex> guard(decodingMutex_);
2782     uint32_t ret;
2783     auto iter = GetValidImageStatus(0, ret);
2784     if (iter == imageStatusMap_.end()) {
2785         IMAGE_LOGE("[ImageSource]get valid image status fail on get filter area, ret:%{public}u.", ret);
2786         return ret;
2787     }
2788     ret = mainDecoder_->GetFilterArea(privacyType, ranges);
2789     if (ret != SUCCESS) {
2790         IMAGE_LOGE("[ImageSource] GetFilterArea fail, ret:%{public}u", ret);
2791         return ret;
2792     }
2793     return SUCCESS;
2794 }
2795 
ReadSourceBuffer(uint32_t bufferSize,uint32_t & errorCode)2796 uint8_t* ImageSource::ReadSourceBuffer(uint32_t bufferSize, uint32_t &errorCode)
2797 {
2798     if (bufferSize > MAX_SOURCE_SIZE) {
2799         IMAGE_LOGE("Invalid buffer size. It's too big. Please check the buffer size.");
2800         errorCode = ERR_IMAGE_SOURCE_DATA;
2801         return nullptr;
2802     }
2803     auto tmpBuffer = new (std::nothrow) uint8_t[bufferSize];
2804     if (tmpBuffer == nullptr) {
2805         IMAGE_LOGE("New buffer failed, bufferSize:%{public}u.", bufferSize);
2806         errorCode = ERR_IMAGE_SOURCE_DATA;
2807         return nullptr;
2808     }
2809     uint32_t savedPosition = sourceStreamPtr_->Tell();
2810     sourceStreamPtr_->Seek(0);
2811     uint32_t readSize = 0;
2812     bool retRead = sourceStreamPtr_->Read(bufferSize, tmpBuffer, bufferSize, readSize);
2813     sourceStreamPtr_->Seek(savedPosition);
2814     if (!retRead) {
2815         IMAGE_LOGE("SourceStream read failed.");
2816         delete[] tmpBuffer;
2817         errorCode = ERR_IMAGE_SOURCE_DATA;
2818         return nullptr;
2819     }
2820     errorCode = SUCCESS;
2821     return tmpBuffer;
2822 }
2823 
GetFilterArea(const std::vector<std::string> & exifKeys,std::vector<std::pair<uint32_t,uint32_t>> & ranges)2824 uint32_t ImageSource::GetFilterArea(const std::vector<std::string> &exifKeys,
2825                                     std::vector<std::pair<uint32_t, uint32_t>> &ranges)
2826 {
2827     std::unique_lock<std::mutex> guard(decodingMutex_);
2828     if (exifKeys.empty()) {
2829         IMAGE_LOGD("GetFilterArea failed, exif key is empty.");
2830         return ERR_IMAGE_INVALID_PARAMETER;
2831     }
2832     if (sourceStreamPtr_ == nullptr) {
2833         IMAGE_LOGD("GetFilterArea failed, sourceStreamPtr is not existed.");
2834         return ERR_IMAGE_SOURCE_DATA;
2835     }
2836     uint32_t bufferSize = sourceStreamPtr_->GetStreamSize();
2837     auto bufferPtr = sourceStreamPtr_->GetDataPtr();
2838     if (bufferPtr != nullptr) {
2839         auto metadataAccessor = MetadataAccessorFactory::Create(bufferPtr, bufferSize);
2840         if (metadataAccessor == nullptr) {
2841             IMAGE_LOGD("Create metadataAccessor failed.");
2842             return E_NO_EXIF_TAG;
2843         }
2844         return metadataAccessor->GetFilterArea(exifKeys, ranges);
2845     }
2846     uint32_t error = SUCCESS;
2847     auto tmpBuffer = ReadSourceBuffer(bufferSize, error);
2848     if (tmpBuffer == nullptr) {
2849         return error;
2850     }
2851 
2852     auto metadataAccessor = MetadataAccessorFactory::Create(tmpBuffer, bufferSize);
2853     if (metadataAccessor == nullptr) {
2854         IMAGE_LOGD("Create metadataAccessor failed.");
2855         delete[] tmpBuffer;
2856         return E_NO_EXIF_TAG;
2857     }
2858     auto ret = metadataAccessor->GetFilterArea(exifKeys, ranges);
2859     delete[] tmpBuffer;
2860     return ret;
2861 }
2862 
SetIncrementalSource(const bool isIncrementalSource)2863 void ImageSource::SetIncrementalSource(const bool isIncrementalSource)
2864 {
2865     isIncrementalSource_ = isIncrementalSource;
2866 }
2867 
IsIncrementalSource()2868 bool ImageSource::IsIncrementalSource()
2869 {
2870     return isIncrementalSource_;
2871 }
2872 
GetFinalOutputStep(const DecodeOptions & opts,PixelMap & pixelMap,bool hasNinePatch)2873 FinalOutputStep ImageSource::GetFinalOutputStep(const DecodeOptions &opts, PixelMap &pixelMap, bool hasNinePatch)
2874 {
2875     ImageInfo info;
2876     pixelMap.GetImageInfo(info);
2877     ImageInfo dstImageInfo;
2878     dstImageInfo.size = opts.desiredSize;
2879     dstImageInfo.pixelFormat = opts.desiredPixelFormat;
2880     if (opts.desiredPixelFormat == PixelFormat::UNKNOWN) {
2881         if (preference_ == MemoryUsagePreference::LOW_RAM && info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
2882             dstImageInfo.pixelFormat = PixelFormat::RGB_565;
2883         } else {
2884             dstImageInfo.pixelFormat = PixelFormat::RGBA_8888;
2885         }
2886     }
2887     // decode use, this value may be changed by real pixelFormat
2888     if (pixelMap.GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) {
2889         dstImageInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
2890     } else {
2891         dstImageInfo.alphaType = pixelMap.GetAlphaType();
2892     }
2893     bool densityChange = HasDensityChange(opts, info, hasNinePatch);
2894     bool sizeChange =
2895         ImageSizeChange(pixelMap.GetWidth(), pixelMap.GetHeight(), opts.desiredSize.width, opts.desiredSize.height);
2896     bool rotateChange = !ImageUtils::FloatCompareZero(opts.rotateDegrees);
2897     bool convertChange = ImageConverChange(opts.CropRect, dstImageInfo, info);
2898     if (sizeChange) {
2899         return FinalOutputStep::SIZE_CHANGE;
2900     }
2901     if (densityChange) {
2902         return FinalOutputStep::DENSITY_CHANGE;
2903     }
2904     if (rotateChange) {
2905         return FinalOutputStep::ROTATE_CHANGE;
2906     }
2907     if (convertChange) {
2908         return FinalOutputStep::CONVERT_CHANGE;
2909     }
2910     return FinalOutputStep::NO_CHANGE;
2911 }
2912 
HasDensityChange(const DecodeOptions & opts,ImageInfo & srcImageInfo,bool hasNinePatch)2913 bool ImageSource::HasDensityChange(const DecodeOptions &opts, ImageInfo &srcImageInfo, bool hasNinePatch)
2914 {
2915     return !hasNinePatch && (srcImageInfo.baseDensity > 0) && (opts.fitDensity > 0) &&
2916         (srcImageInfo.baseDensity != opts.fitDensity);
2917 }
2918 
ImageSizeChange(int32_t width,int32_t height,int32_t desiredWidth,int32_t desiredHeight)2919 bool ImageSource::ImageSizeChange(int32_t width, int32_t height, int32_t desiredWidth, int32_t desiredHeight)
2920 {
2921     bool sizeChange = false;
2922     if (desiredWidth > 0 && desiredHeight > 0 && width > 0 && height > 0) {
2923         float scaleX = static_cast<float>(desiredWidth) / static_cast<float>(width);
2924         float scaleY = static_cast<float>(desiredHeight) / static_cast<float>(height);
2925         if ((fabs(scaleX - 1.0f) >= EPSILON) && (fabs(scaleY - 1.0f) >= EPSILON)) {
2926             sizeChange = true;
2927         }
2928     }
2929     return sizeChange;
2930 }
2931 
ImageConverChange(const Rect & cropRect,ImageInfo & dstImageInfo,ImageInfo & srcImageInfo)2932 bool ImageSource::ImageConverChange(const Rect &cropRect, ImageInfo &dstImageInfo, ImageInfo &srcImageInfo)
2933 {
2934     bool hasPixelConvert = false;
2935     dstImageInfo.alphaType = ImageUtils::GetValidAlphaTypeByFormat(dstImageInfo.alphaType, dstImageInfo.pixelFormat);
2936     if (dstImageInfo.pixelFormat != srcImageInfo.pixelFormat || dstImageInfo.alphaType != srcImageInfo.alphaType) {
2937         hasPixelConvert = true;
2938     }
2939     CropValue value = PostProc::GetCropValue(cropRect, srcImageInfo.size);
2940     if (value == CropValue::NOCROP && !hasPixelConvert) {
2941         IMAGE_LOGD("[ImageSource]no need crop and pixel convert.");
2942         return false;
2943     } else if (value == CropValue::INVALID) {
2944         IMAGE_LOGE("[ImageSource]invalid corp region, top:%{public}d, left:%{public}d, "
2945             "width:%{public}d, height:%{public}d",
2946             cropRect.top, cropRect.left, cropRect.width, cropRect.height);
2947         return false;
2948     }
2949     return true;
2950 }
2951 
strnstr(const char * data,const char * base64Url,size_t len)2952 char *strnstr(const char *data, const char *base64Url, size_t len)
2953 {
2954     size_t base64UrlLen = strlen(base64Url);
2955     while (len >= base64UrlLen) {
2956         len--;
2957         if (!memcmp(data, base64Url, base64UrlLen))
2958             return (char *)data;
2959         data++;
2960     }
2961     return nullptr;
2962 }
2963 
DecodeBase64(const uint8_t * data,uint32_t size)2964 unique_ptr<SourceStream> ImageSource::DecodeBase64(const uint8_t *data, uint32_t size)
2965 {
2966     if (size < IMAGE_URL_PREFIX.size() ||
2967         ::memcmp(data, IMAGE_URL_PREFIX.c_str(), IMAGE_URL_PREFIX.size()) != INT_ZERO) {
2968         IMAGE_LOGD("[ImageSource]Base64 image header mismatch.");
2969         return nullptr;
2970     }
2971     if (size > MAX_SOURCE_SIZE) {
2972         IMAGE_LOGE("%{public}s input size %{public}u is too large.", __func__, size);
2973         return nullptr;
2974     }
2975     const char *data1 = reinterpret_cast<const char *>(data);
2976     auto sub = strnstr(data1, BASE64_URL_PREFIX.c_str(), static_cast<size_t>(size));
2977     if (sub == nullptr) {
2978         IMAGE_LOGI("[ImageSource]Base64 mismatch.");
2979         return nullptr;
2980     }
2981     sub = sub + BASE64_URL_PREFIX.size();
2982     uint32_t subSize = size - (sub - data1);
2983     IMAGE_LOGD("[ImageSource]Base64 image input: size %{public}u.", subSize);
2984     if (subSize == 0) {
2985         IMAGE_LOGE("%{public}s input subsize is %{public}u.", __func__, subSize);
2986         return nullptr;
2987     }
2988 
2989     std::unique_ptr<uint8_t[]> dataCopy;
2990     if (sub[subSize - 1] != '\0') {
2991         dataCopy = make_unique<uint8_t[]>(subSize + 1);
2992         if (dataCopy == nullptr) {
2993             IMAGE_LOGE("[ImageSource]Base64 malloc data buffer fail.");
2994             return nullptr;
2995         }
2996         errno_t ret = memcpy_s(dataCopy.get(), subSize, sub, subSize);
2997         dataCopy[subSize] = '\0';
2998         sub = reinterpret_cast<char *>(dataCopy.get());
2999         subSize++;
3000         if (ret != EOK) {
3001             IMAGE_LOGE("[ImageSource]Base64 copy data fail, ret:%{public}d", ret);
3002             return nullptr;
3003         }
3004     }
3005 
3006 #ifdef NEW_SKIA
3007     size_t outputLen = 0;
3008     SkBase64::Error error = SkBase64::Decode(sub, subSize, nullptr, &outputLen);
3009     bool cond = error != SkBase64::Error::kNoError;
3010     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "[ImageSource]Base64 decode get out size failed.");
3011 
3012     sk_sp<SkData> resData = SkData::MakeUninitialized(outputLen);
3013     error = SkBase64::Decode(sub, subSize, resData->writable_data(), &outputLen);
3014     cond = error != SkBase64::Error::kNoError;
3015     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "[ImageSource]Base64 decode get data failed.");
3016     IMAGE_LOGD("[ImageSource][NewSkia]Create BufferSource from decoded base64 string.");
3017     auto imageData = static_cast<const uint8_t *>(resData->data());
3018     return BufferSourceStream::CreateSourceStream(imageData, resData->size());
3019 #else
3020     SkBase64 base64Decoder;
3021     if (base64Decoder.decode(sub, subSize) != SkBase64::kNoError) {
3022         IMAGE_LOGE("[ImageSource]base64 image decode failed!");
3023         return nullptr;
3024     }
3025     auto base64Data = base64Decoder.getData();
3026     const uint8_t *imageData = reinterpret_cast<uint8_t *>(base64Data);
3027     IMAGE_LOGD("[ImageSource]Create BufferSource from decoded base64 string.");
3028     auto result = BufferSourceStream::CreateSourceStream(imageData, base64Decoder.getDataSize());
3029     if (base64Data != nullptr) {
3030         delete[] base64Data;
3031         base64Data = nullptr;
3032     }
3033     return result;
3034 #endif
3035 }
3036 
DecodeBase64(const string & data)3037 unique_ptr<SourceStream> ImageSource::DecodeBase64(const string &data)
3038 {
3039     return DecodeBase64(reinterpret_cast<const uint8_t *>(data.c_str()), data.size());
3040 }
3041 
IsSpecialYUV()3042 bool ImageSource::IsSpecialYUV()
3043 {
3044     const bool isBufferSource =
3045         (sourceStreamPtr_ != nullptr) && (sourceStreamPtr_->GetStreamType() == ImagePlugin::BUFFER_SOURCE_TYPE);
3046     const bool isSizeValid = (sourceOptions_.size.width > 0) && (sourceOptions_.size.height > 0);
3047     const bool isYUV =
3048         (sourceOptions_.pixelFormat == PixelFormat::NV12) || (sourceOptions_.pixelFormat == PixelFormat::NV21);
3049     return (isBufferSource && isSizeValid && isYUV);
3050 }
3051 
FloatToUint8(float f)3052 static inline uint8_t FloatToUint8(float f)
3053 {
3054     int data = static_cast<int>(f + 0.5f);
3055     if (data < 0) {
3056         data = 0;
3057     } else if (data > UINT8_MAX) {
3058         data = UINT8_MAX;
3059     }
3060     return static_cast<uint8_t>(data);
3061 }
3062 
ConvertYUV420ToRGBA(uint8_t * data,uint32_t size,bool isSupportOdd,bool isAddUV,uint32_t & errorCode)3063 bool ImageSource::ConvertYUV420ToRGBA(uint8_t *data, uint32_t size, bool isSupportOdd, bool isAddUV,
3064     uint32_t &errorCode)
3065 {
3066     IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA IN srcPixelFormat:%{public}d, srcSize:(%{public}d,"
3067         "%{public}d)",
3068         sourceOptions_.pixelFormat, sourceOptions_.size.width, sourceOptions_.size.height);
3069     if ((!isSupportOdd) && (static_cast<uint32_t>(sourceOptions_.size.width) & 1) == 1) {
3070         IMAGE_LOGE("[ImageSource]ConvertYUV420ToRGBA odd width, %{public}d", sourceOptions_.size.width);
3071         errorCode = ERR_IMAGE_DATA_UNSUPPORT;
3072         return false;
3073     }
3074 
3075     const size_t width = static_cast<size_t>(sourceOptions_.size.width);
3076     const size_t height = static_cast<size_t>(sourceOptions_.size.height);
3077     const size_t uvwidth = (isSupportOdd && isAddUV) ? (width + (width & 1)) : width;
3078     const uint8_t *yuvPlane = sourceStreamPtr_->GetDataPtr();
3079     const size_t yuvSize = sourceStreamPtr_->GetStreamSize();
3080     const size_t ubase = width * height + ((sourceOptions_.pixelFormat == PixelFormat::NV12) ? 0 : 1);
3081     const size_t vbase = width * height + ((sourceOptions_.pixelFormat == PixelFormat::NV12) ? 1 : 0);
3082     IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA uvbase:(%{public}zu, %{public}zu),"
3083         "width:(%{public}zu, %{public}zu)",
3084         ubase, vbase, width, uvwidth);
3085 
3086     for (size_t h = 0; h < height; h++) {
3087         const size_t yline = h * width;
3088         const size_t uvline = (h >> 1) * uvwidth;
3089 
3090         for (size_t w = 0; w < width; w++) {
3091             const size_t ypos = yline + w;
3092             const size_t upos = ubase + uvline + (w & (~1));
3093             const size_t vpos = vbase + uvline + (w & (~1));
3094             const uint8_t y = (ypos < yuvSize) ? yuvPlane[ypos] : 0;
3095             const uint8_t u = (upos < yuvSize) ? yuvPlane[upos] : 0;
3096             const uint8_t v = (vpos < yuvSize) ? yuvPlane[vpos] : 0;
3097             // jpeg
3098             const uint8_t r = FloatToUint8((1.0f * y) + (1.402f * v) - (0.703749f * UINT8_MAX));
3099             const uint8_t g = FloatToUint8((1.0f * y) - (0.344136f * u) - (0.714136f * v) + (0.531211f * UINT8_MAX));
3100             const uint8_t b = FloatToUint8((1.0f * y) + (1.772f * u) - (0.889475f * UINT8_MAX));
3101 
3102             const size_t rgbpos = ypos << 2;
3103             if ((rgbpos + NUM_3) < size) {
3104                 data[rgbpos + NUM_0] = r;
3105                 data[rgbpos + NUM_1] = g;
3106                 data[rgbpos + NUM_2] = b;
3107                 data[rgbpos + NUM_3] = UINT8_MAX;
3108             }
3109         }
3110     }
3111     IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA OUT");
3112     return true;
3113 }
3114 
CreatePixelMapForYUV(uint32_t & errorCode)3115 unique_ptr<PixelMap> ImageSource::CreatePixelMapForYUV(uint32_t &errorCode)
3116 {
3117     IMAGE_LOGD("Starting the creation of PixelMap for YUV. Source pixel format: %{public}d, "
3118         "Source size: (%{public}d, %{public}d)",
3119         sourceOptions_.pixelFormat, sourceOptions_.size.width, sourceOptions_.size.height);
3120     DumpInputData("yuv");
3121 
3122     unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
3123     if (pixelMap == nullptr) {
3124         IMAGE_LOGE("Failed to create the pixel map unique_ptr.");
3125         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
3126         return nullptr;
3127     }
3128 
3129     ImageInfo info;
3130     info.baseDensity = sourceOptions_.baseDensity;
3131     info.size.width = sourceOptions_.size.width;
3132     info.size.height = sourceOptions_.size.height;
3133     info.pixelFormat = PixelFormat::RGBA_8888;
3134     info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
3135     errorCode = pixelMap->SetImageInfo(info);
3136     if (errorCode != SUCCESS) {
3137         IMAGE_LOGE("Error updating pixelmap info. Return code: %{public}u.", errorCode);
3138         return nullptr;
3139     }
3140     bool cond = ImageUtils::CheckMulOverflow(pixelMap->GetWidth(), pixelMap->GetHeight(), pixelMap->GetPixelBytes());
3141     CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "Invalid pixelmap params width:%{public}d, height:%{public}d",
3142                                pixelMap->GetWidth(), pixelMap->GetHeight());
3143     size_t bufferSize = static_cast<size_t>(pixelMap->GetWidth() * pixelMap->GetHeight() * pixelMap->GetPixelBytes());
3144     auto buffer = malloc(bufferSize);
3145     if (buffer == nullptr) {
3146         IMAGE_LOGE("Failed to allocate memory of size %{public}zu", bufferSize);
3147         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
3148         return nullptr;
3149     }
3150 
3151     pixelMap->SetEditable(false);
3152     pixelMap->SetPixelsAddr(buffer, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
3153 
3154     if (!ConvertYUV420ToRGBA(static_cast<uint8_t *>(buffer), bufferSize, false, false, errorCode)) {
3155         IMAGE_LOGE("Issue converting yuv420 to rgba, errorCode=%{public}u", errorCode);
3156         errorCode = ERROR;
3157         return nullptr;
3158     }
3159 
3160     IMAGE_LOGD("CreatePixelMapForYUV operation completed.");
3161 
3162     if (CreatExifMetadataByImageSource() == SUCCESS) {
3163         auto metadataPtr = exifMetadata_->Clone();
3164         pixelMap->SetExifMetadata(metadataPtr);
3165     }
3166 
3167     if (!ImageUtils::FloatCompareZero(opts_.rotateDegrees)) {
3168         pixelMap->rotate(opts_.rotateDegrees);
3169     } else if (opts_.rotateNewDegrees != INT_ZERO) {
3170         pixelMap->rotate(opts_.rotateNewDegrees);
3171     }
3172 
3173     return pixelMap;
3174 }
3175 
IsASTC(const uint8_t * fileData,size_t fileSize)3176 bool ImageSource::IsASTC(const uint8_t *fileData, size_t fileSize) __attribute__((no_sanitize("cfi")))
3177 {
3178     if (fileData == nullptr || fileSize < ASTC_HEADER_SIZE) {
3179         IMAGE_LOGE("[ImageSource]IsASTC fileData incorrect.");
3180         return false;
3181     }
3182     uint32_t magicVal = static_cast<uint32_t>(fileData[NUM_0]) +
3183         (static_cast<uint32_t>(fileData[NUM_1]) << NUM_8) +
3184         (static_cast<uint32_t>(fileData[NUM_2]) << NUM_16) +
3185         (static_cast<uint32_t>(fileData[NUM_3]) << NUM_24);
3186     if (magicVal == ASTC_MAGIC_ID) {
3187         return true;
3188     }
3189 #ifdef SUT_DECODE_ENABLE
3190     if (magicVal == SUT_FILE_SIGNATURE) {
3191         return true;
3192     }
3193 #endif
3194     return false;
3195 }
3196 
GetImageInfoForASTC(ImageInfo & imageInfo,const uint8_t * sourceFilePtr)3197 bool ImageSource::GetImageInfoForASTC(ImageInfo &imageInfo, const uint8_t *sourceFilePtr)
3198 {
3199     ASTCInfo astcInfo;
3200     if (!sourceStreamPtr_) {
3201         IMAGE_LOGE("[ImageSource] get astc image info null.");
3202         return false;
3203     }
3204     if (!GetASTCInfo(sourceFilePtr, sourceStreamPtr_->GetStreamSize(), astcInfo)) {
3205         IMAGE_LOGE("[ImageSource] get astc image info failed.");
3206         return false;
3207     }
3208     imageInfo.size = astcInfo.size;
3209     switch (astcInfo.blockFootprint.width) {
3210         case NUM_4: {
3211             imageInfo.pixelFormat = PixelFormat::ASTC_4x4;
3212             break;
3213         }
3214         case NUM_6: {
3215             imageInfo.pixelFormat = PixelFormat::ASTC_6x6;
3216             break;
3217         }
3218         case NUM_8: {
3219             imageInfo.pixelFormat = PixelFormat::ASTC_8x8;
3220             break;
3221         }
3222         default:
3223             IMAGE_LOGE("[ImageSource]GetImageInfoForASTC pixelFormat is unknown.");
3224             imageInfo.pixelFormat = PixelFormat::UNKNOWN;
3225     }
3226     return true;
3227 }
3228 
3229 enum class AstcExtendInfoType : uint8_t {
3230     COLOR_SPACE = 0
3231 };
3232 
3233 #ifdef SUT_DECODE_ENABLE
GetAstcSizeBytes(const uint8_t * fileBuf,size_t fileSize)3234 static size_t GetAstcSizeBytes(const uint8_t *fileBuf, size_t fileSize)
3235 {
3236     bool cond = (fileBuf == nullptr) || (fileSize <= ASTC_HEAD_BYTES);
3237     CHECK_ERROR_RETURN_RET_LOG(cond, 0,
3238                                "astc GetAstcSizeBytes input is nullptr or fileSize is smaller than ASTC HEADER");
3239     cond = !g_sutDecSoManager.LoadSutDecSo() || g_sutDecSoManager.sutDecSoGetSizeFunc_ == nullptr;
3240     CHECK_ERROR_RETURN_RET_LOG(cond, 0,
3241                                "[ImageSource] SUT dec so dlopen failed or sutDecSoGetSizeFunc_ is nullptr!");
3242     return g_sutDecSoManager.sutDecSoGetSizeFunc_(fileBuf, fileSize);
3243 }
3244 
FreeAllExtMemSut(AstcOutInfo & astcInfo)3245 static void FreeAllExtMemSut(AstcOutInfo &astcInfo)
3246 {
3247     for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {
3248         if (astcInfo.expandInfoBuf[idx] != nullptr) {
3249             free(astcInfo.expandInfoBuf[idx]);
3250         }
3251     }
3252 }
3253 
FillAstcSutExtInfo(AstcOutInfo & astcInfo,SutInInfo & sutInfo)3254 static bool FillAstcSutExtInfo(AstcOutInfo &astcInfo, SutInInfo &sutInfo)
3255 {
3256     bool cond = !g_sutDecSoManager.LoadSutDecSo() || g_sutDecSoManager.getExpandInfoFromSutFunc_ == nullptr;
3257     CHECK_ERROR_RETURN_RET_LOG(cond, false, "[ImageSource] SUT dec getExpandInfoFromSutFunc_ is nullptr!");
3258     cond = !g_sutDecSoManager.getExpandInfoFromSutFunc_(sutInfo, astcInfo, false);
3259     CHECK_ERROR_RETURN_RET_LOG(cond, false, "[ImageSource] GetExpandInfoFromSut failed!");
3260     int32_t expandTotalBytes = 0;
3261     for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {
3262         astcInfo.expandInfoCapacity[idx] = astcInfo.expandInfoBytes[idx];
3263         astcInfo.expandInfoBuf[idx] = static_cast<uint8_t *>(malloc(astcInfo.expandInfoCapacity[idx]));
3264         if (astcInfo.expandInfoBuf[idx] == nullptr) {
3265             IMAGE_LOGE("[ImageSource] astcInfo.expandInfoBuf malloc failed!");
3266             return false;
3267         }
3268         expandTotalBytes += sizeof(uint8_t) + sizeof(int32_t) + astcInfo.expandInfoBytes[idx];
3269     }
3270     return astcInfo.expandTotalBytes == expandTotalBytes;
3271 }
3272 
CheckExtInfoForPixelmap(AstcOutInfo & astcInfo,unique_ptr<PixelAstc> & pixelAstc)3273 static bool CheckExtInfoForPixelmap(AstcOutInfo &astcInfo, unique_ptr<PixelAstc> &pixelAstc)
3274 {
3275     uint8_t colorSpace = 0;
3276     for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {
3277         if (astcInfo.expandInfoBuf[idx] != nullptr) {
3278             switch (static_cast<AstcExtendInfoType>(astcInfo.expandInfoType[idx])) {
3279                 case AstcExtendInfoType::COLOR_SPACE:
3280                     colorSpace = *astcInfo.expandInfoBuf[idx];
3281                     break;
3282                 default:
3283                     return false;
3284             }
3285         }
3286     }
3287 #ifdef IMAGE_COLORSPACE_FLAG
3288     pixelAstc->InnerSetColorSpace(static_cast<ColorManager::ColorSpaceName>(colorSpace), true);
3289 #endif
3290     return true;
3291 }
3292 
TextureSuperCompressDecodeInit(AstcOutInfo * astcInfo,SutInInfo * sutInfo,size_t inBytes,size_t outBytes)3293 static bool TextureSuperCompressDecodeInit(AstcOutInfo *astcInfo, SutInInfo *sutInfo, size_t inBytes, size_t outBytes)
3294 {
3295     bool ret = (memset_s(astcInfo, sizeof(AstcOutInfo), 0, sizeof(AstcOutInfo)) == 0) &&
3296                (memset_s(sutInfo, sizeof(SutInInfo), 0, sizeof(SutInInfo)) == 0);
3297     if (!ret) {
3298         IMAGE_LOGE("astc SuperDecompressTexture memset failed!");
3299         return false;
3300     }
3301     bool cond = inBytes > static_cast<size_t>(std::numeric_limits<int32_t>::max());
3302     CHECK_ERROR_RETURN_RET_LOG(cond, false, "astc SuperDecompressTexture inBytes overflow!");
3303     sutInfo->sutBytes = static_cast<int32_t>(inBytes);
3304     cond = outBytes > static_cast<size_t>(std::numeric_limits<int32_t>::max());
3305     CHECK_ERROR_RETURN_RET_LOG(cond, false, "astc SuperDecompressTexture outBytes overflow!");
3306     astcInfo->astcBytes = static_cast<int32_t>(outBytes);
3307     return true;
3308 }
3309 
TextureSuperCompressDecode(const uint8_t * inData,size_t inBytes,uint8_t * outData,size_t outBytes,unique_ptr<PixelAstc> & pixelAstc)3310 static bool TextureSuperCompressDecode(const uint8_t *inData, size_t inBytes, uint8_t *outData, size_t outBytes,
3311     unique_ptr<PixelAstc> &pixelAstc)
3312 {
3313     size_t preOutBytes = outBytes;
3314     bool cond = (inData == nullptr) || (outData == nullptr);
3315     CHECK_ERROR_RETURN_RET_LOG(cond, false, "astc TextureSuperCompressDecode input check failed!");
3316     cond = !g_sutDecSoManager.LoadSutDecSo() || g_sutDecSoManager.sutDecSoDecFunc_ == nullptr;
3317     CHECK_ERROR_RETURN_RET_LOG(cond, false,
3318         "[ImageSource] SUT dec so dlopen failed or sutDecSoDecFunc_ is nullptr!");
3319     AstcOutInfo astcInfo = {0};
3320     SutInInfo sutInfo = {0};
3321     cond = !TextureSuperCompressDecodeInit(&astcInfo, &sutInfo, inBytes, outBytes);
3322     CHECK_ERROR_RETURN_RET(cond, false);
3323     sutInfo.sutBuf = inData;
3324     astcInfo.astcBuf = outData;
3325     if (!FillAstcSutExtInfo(astcInfo, sutInfo)) {
3326         FreeAllExtMemSut(astcInfo);
3327         IMAGE_LOGE("[ImageSource] SUT dec FillAstcSutExtInfo failed!");
3328         return false;
3329     }
3330     if (!g_sutDecSoManager.sutDecSoDecFunc_(sutInfo, astcInfo)) {
3331         IMAGE_LOGE("astc SuperDecompressTexture process failed!");
3332         FreeAllExtMemSut(astcInfo);
3333         return false;
3334     }
3335     if (!CheckExtInfoForPixelmap(astcInfo, pixelAstc)) {
3336         IMAGE_LOGE("astc SuperDecompressTexture could not get ext info!");
3337         FreeAllExtMemSut(astcInfo);
3338         return false;
3339     }
3340     FreeAllExtMemSut(astcInfo);
3341     cond = astcInfo.astcBytes < 0;
3342     CHECK_ERROR_RETURN_RET_LOG(cond, false, "astc SuperDecompressTexture astcInfo.astcBytes sub overflow!");
3343     outBytes = static_cast<size_t>(astcInfo.astcBytes);
3344     cond = outBytes != preOutBytes;
3345     CHECK_ERROR_RETURN_RET_LOG(cond, false, "astc SuperDecompressTexture Dec size is predicted failed!");
3346     return true;
3347 }
3348 #endif
3349 
GetDataSize(uint8_t * buf)3350 static uint32_t GetDataSize(uint8_t *buf)
3351 {
3352     return static_cast<uint32_t>(buf[NUM_0]) +
3353         (static_cast<uint32_t>(buf[NUM_1]) << NUM_8) +
3354         (static_cast<uint32_t>(buf[NUM_2]) << NUM_16) +
3355         (static_cast<uint32_t>(buf[NUM_3]) << NUM_24);
3356 }
3357 
ReleaseExtendInfoMemory(AstcExtendInfo & extendInfo)3358 void ReleaseExtendInfoMemory(AstcExtendInfo &extendInfo)
3359 {
3360     for (uint8_t idx = 0; idx < extendInfo.extendNums; idx++) {
3361         if (extendInfo.extendInfoValue[idx] != nullptr) {
3362             free(extendInfo.extendInfoValue[idx]);
3363             extendInfo.extendInfoValue[idx] = nullptr;
3364         }
3365     }
3366 }
3367 
GetExtInfoForPixelAstc(AstcExtendInfo & extInfo,unique_ptr<PixelAstc> & pixelAstc)3368 static bool GetExtInfoForPixelAstc(AstcExtendInfo &extInfo, unique_ptr<PixelAstc> &pixelAstc)
3369 {
3370     uint8_t colorSpace = 0;
3371     for (uint8_t idx = 0; idx < extInfo.extendNums; idx++) {
3372         switch (static_cast<AstcExtendInfoType>(extInfo.extendInfoType[idx])) {
3373             case AstcExtendInfoType::COLOR_SPACE:
3374                 colorSpace = *extInfo.extendInfoValue[idx];
3375                 break;
3376             default:
3377                 return false;
3378         }
3379     }
3380 #ifdef IMAGE_COLORSPACE_FLAG
3381     ColorManager::ColorSpace grColorspace (static_cast<ColorManager::ColorSpaceName>(colorSpace));
3382     pixelAstc->InnerSetColorSpace(grColorspace, true);
3383 #endif
3384     return true;
3385 }
3386 
ExtInfoColorSpaceCheck(AstcExtendInfo & extInfo)3387 static bool ExtInfoColorSpaceCheck(AstcExtendInfo &extInfo)
3388 {
3389     int32_t leftBytes = static_cast<int32_t>(extInfo.extendBufferSumBytes);
3390     if (leftBytes != ASTC_EXTEND_INFO_TLV_SUM_BYTES) {
3391         IMAGE_LOGE("ExtInfoColorSpaceCheck colorspace TLV decode size failed. bytes:%{public}d", leftBytes);
3392         return false;
3393     }
3394     if (extInfo.extendInfoLength[extInfo.extendNums] != ASTC_EXTEND_INFO_TLV_NUM) {
3395         IMAGE_LOGE("ExtInfoColorSpaceCheck colorspace TLV decode length failed. length: %{public}d",
3396             extInfo.extendInfoLength[extInfo.extendNums]);
3397         return false;
3398     }
3399     return true;
3400 }
3401 
CheckAstcExtInfoBytes(AstcExtendInfo & extInfo,size_t astcSize,size_t fileSize)3402 static bool CheckAstcExtInfoBytes(AstcExtendInfo &extInfo, size_t astcSize, size_t fileSize)
3403 {
3404     if (extInfo.extendBufferSumBytes != ASTC_EXTEND_INFO_TLV_SUM_BYTES) {
3405         IMAGE_LOGE("CheckAstcExtInfoBytes extendBufferSumBytes is invalid: %{public}d", extInfo.extendBufferSumBytes);
3406         return false;
3407     }
3408     if (extInfo.extendBufferSumBytes + astcSize + ASTC_EXTEND_INFO_SIZE_DEFINITION_LENGTH != fileSize) {
3409         IMAGE_LOGE("CheckAstcExtInfoBytes extendBufferSumBytes is large than filesize");
3410         return false;
3411     }
3412     return true;
3413 }
3414 
ResolveExtInfo(const uint8_t * sourceFilePtr,size_t astcSize,size_t fileSize,unique_ptr<PixelAstc> & pixelAstc)3415 static bool ResolveExtInfo(const uint8_t *sourceFilePtr, size_t astcSize, size_t fileSize,
3416     unique_ptr<PixelAstc> &pixelAstc)
3417 {
3418     uint8_t *extInfoBuf = const_cast<uint8_t*>(sourceFilePtr) + astcSize;
3419     /* */
3420     AstcExtendInfo extInfo = {0};
3421     bool invalidData = (astcSize + ASTC_EXTEND_INFO_SIZE_DEFINITION_LENGTH >= fileSize) ||
3422         (memset_s(&extInfo, sizeof(AstcExtendInfo), 0, sizeof(AstcExtendInfo)) != 0);
3423     if (invalidData) {
3424         IMAGE_LOGE("ResolveExtInfo file data is invalid!");
3425         return false;
3426     }
3427     extInfo.extendBufferSumBytes = GetDataSize(extInfoBuf);
3428     if (!CheckAstcExtInfoBytes(extInfo, astcSize, fileSize)) {
3429         IMAGE_LOGE("ResolveExtInfo file size is not equal to astc add ext bytes!");
3430         return false;
3431     }
3432     extInfoBuf += ASTC_EXTEND_INFO_SIZE_DEFINITION_LENGTH;
3433     int32_t leftBytes = static_cast<int32_t>(extInfo.extendBufferSumBytes);
3434     for (; leftBytes > 0;) {
3435         if (extInfo.extendNums >= ASTC_EXTEND_INFO_TLV_NUM) {
3436             return false;
3437         }
3438         extInfo.extendInfoType[extInfo.extendNums] = *extInfoBuf++;
3439         leftBytes--;
3440         extInfo.extendInfoLength[extInfo.extendNums] = GetDataSize(extInfoBuf);
3441         if (!ExtInfoColorSpaceCheck(extInfo)) {
3442             return false;
3443         }
3444         leftBytes -= ASTC_EXTEND_INFO_LENGTH_LENGTH;
3445         extInfoBuf += ASTC_EXTEND_INFO_LENGTH_LENGTH;
3446         if (extInfo.extendInfoLength[extInfo.extendNums] > 0) {
3447             extInfo.extendInfoValue[extInfo.extendNums] =
3448                 static_cast<uint8_t*>(malloc(extInfo.extendInfoLength[extInfo.extendNums]));
3449             bool ret = (extInfo.extendInfoValue[extInfo.extendNums] != nullptr) &&
3450                 (memcpy_s(extInfo.extendInfoValue[extInfo.extendNums], extInfo.extendInfoLength[extInfo.extendNums],
3451                 extInfoBuf, extInfo.extendInfoLength[extInfo.extendNums]) == 0);
3452             if (!ret) {
3453                 ReleaseExtendInfoMemory(extInfo);
3454                 return false;
3455             }
3456             leftBytes -= static_cast<int32_t>(extInfo.extendInfoLength[extInfo.extendNums]);
3457             extInfoBuf += extInfo.extendInfoLength[extInfo.extendNums];
3458         }
3459         extInfo.extendNums++;
3460     }
3461     if (!GetExtInfoForPixelAstc(extInfo, pixelAstc)) {
3462         IMAGE_LOGE("ResolveExtInfo Could not get ext info!");
3463     }
3464     ReleaseExtendInfoMemory(extInfo);
3465     return true;
3466 }
3467 
3468 #ifdef SUT_DECODE_ENABLE
FormatIsSUT(const uint8_t * fileData,size_t fileSize)3469 static bool FormatIsSUT(const uint8_t *fileData, size_t fileSize)
3470 {
3471     if (fileData == nullptr || fileSize < SUT_HEAD_BYTES) {
3472         IMAGE_LOGE("FormatIsSUT fileData incorrect.");
3473         return false;
3474     }
3475     uint32_t magicVal = static_cast<uint32_t>(fileData[NUM_0]) +
3476         (static_cast<uint32_t>(fileData[NUM_1]) << NUM_8) +
3477         (static_cast<uint32_t>(fileData[NUM_2]) << NUM_16) +
3478         (static_cast<uint32_t>(fileData[NUM_3]) << NUM_24);
3479     return magicVal == SUT_FILE_SIGNATURE;
3480 }
3481 #endif
3482 
ReadFileAndResoveAstc(size_t fileSize,size_t astcSize,unique_ptr<PixelAstc> & pixelAstc,const uint8_t * sourceFilePtr,const DecodeOptions & opts)3483 static bool ReadFileAndResoveAstc(size_t fileSize, size_t astcSize, unique_ptr<PixelAstc> &pixelAstc,
3484     const uint8_t *sourceFilePtr, const DecodeOptions &opts)
3485 {
3486 #if !(defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM))
3487     Size desiredSize = {astcSize, 1};
3488     MemoryData memoryData = {nullptr, astcSize, "CreatePixelMapForASTC Data", desiredSize, pixelAstc->GetPixelFormat()};
3489     ImageInfo pixelAstcInfo;
3490     pixelAstc->GetImageInfo(pixelAstcInfo);
3491     AllocatorType allocatorType = (opts.allocatorType == AllocatorType::DEFAULT) ?
3492         (IsSupportAstcZeroCopy(pixelAstcInfo.size) ? AllocatorType::DMA_ALLOC : AllocatorType::SHARE_MEM_ALLOC) :
3493         opts.allocatorType;
3494     std::unique_ptr<AbsMemory> dstMemory = MemoryManager::CreateMemory(allocatorType, memoryData);
3495     if (dstMemory == nullptr) {
3496         IMAGE_LOGE("ReadFileAndResoveAstc CreateMemory failed");
3497         return false;
3498     }
3499     pixelAstc->SetPixelsAddr(dstMemory->data.data, dstMemory->extend.data, dstMemory->data.size, dstMemory->GetType(),
3500         nullptr);
3501     bool successMemCpyOrDec = true;
3502 #ifdef SUT_DECODE_ENABLE
3503     if (FormatIsSUT(sourceFilePtr, fileSize)) {
3504         successMemCpyOrDec = TextureSuperCompressDecode(sourceFilePtr, fileSize,
3505             static_cast<uint8_t *>(dstMemory->data.data), astcSize, pixelAstc);
3506         IMAGE_LOGD("ReadFileAndResoveAstc colorspace %{public}d",
3507             pixelAstc->InnerGetGrColorSpace().GetColorSpaceName());
3508     } else {
3509 #endif
3510         if (memcpy_s(dstMemory->data.data, astcSize, sourceFilePtr, astcSize) != 0) {
3511             IMAGE_LOGE("[ImageSource] astc memcpy_s failed!");
3512             successMemCpyOrDec = false;
3513         }
3514         successMemCpyOrDec = successMemCpyOrDec && ((fileSize == astcSize) ||
3515             ((fileSize > astcSize) && ResolveExtInfo(sourceFilePtr, astcSize, fileSize, pixelAstc)));
3516 #ifdef SUT_DECODE_ENABLE
3517     }
3518 #endif
3519     if (!successMemCpyOrDec) {
3520         return false;
3521     }
3522 #endif
3523     return true;
3524 }
3525 
CreatePixelMapForASTC(uint32_t & errorCode,const DecodeOptions & opts)3526 unique_ptr<PixelMap> ImageSource::CreatePixelMapForASTC(uint32_t &errorCode, const DecodeOptions &opts)
3527 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
3528 {
3529     errorCode = ERROR;
3530     return nullptr;
3531 }
3532 #else
3533 {
3534     ImageTrace imageTrace("CreatePixelMapForASTC");
3535     unique_ptr<PixelAstc> pixelAstc = make_unique<PixelAstc>();
3536     ImageInfo info;
3537     uint8_t *sourceFilePtr = sourceStreamPtr_->GetDataPtr();
3538     if (!GetImageInfoForASTC(info, sourceFilePtr)) {
3539         IMAGE_LOGE("[ImageSource] get astc image info failed.");
3540         return nullptr;
3541     }
3542     errorCode = pixelAstc->SetImageInfo(info);
3543     pixelAstc->SetAstcRealSize(info.size);
3544     if (errorCode != SUCCESS) {
3545         IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
3546         return nullptr;
3547     }
3548     pixelAstc->SetEditable(false);
3549     size_t fileSize = sourceStreamPtr_->GetStreamSize();
3550     bool isSUT = false;
3551 #ifdef SUT_DECODE_ENABLE
3552     isSUT = FormatIsSUT(sourceFilePtr, fileSize);
3553     size_t astcSize = !isSUT ?
3554         ImageUtils::GetAstcBytesCount(info) : GetAstcSizeBytes(sourceFilePtr, fileSize);
3555     if (astcSize == 0) {
3556         IMAGE_LOGE("[ImageSource] astc GetAstcSizeBytes failed.");
3557         return nullptr;
3558     }
3559 #else
3560     size_t astcSize = ImageUtils::GetAstcBytesCount(info);
3561 #endif
3562     if (!isSUT && astcSize > fileSize) {
3563         IMAGE_LOGE("[ImageSource] astcSize > fileSize.");
3564         return nullptr;
3565     }
3566     if (!ReadFileAndResoveAstc(fileSize, astcSize, pixelAstc, sourceFilePtr, opts)) {
3567         IMAGE_LOGE("[ImageSource] astc ReadFileAndResoveAstc failed.");
3568         return nullptr;
3569     }
3570     pixelAstc->SetAstc(true);
3571     ImageUtils::FlushSurfaceBuffer(pixelAstc.get());
3572     return pixelAstc;
3573 }
3574 #endif
3575 
GetASTCInfo(const uint8_t * fileData,size_t fileSize,ASTCInfo & astcInfo)3576 bool ImageSource::GetASTCInfo(const uint8_t *fileData, size_t fileSize, ASTCInfo &astcInfo)
3577 {
3578     if (fileData == nullptr || fileSize < ASTC_HEADER_SIZE) {
3579         IMAGE_LOGE("[ImageSource]GetASTCInfo fileData incorrect.");
3580         return false;
3581     }
3582     uint32_t magicVal = static_cast<uint32_t>(fileData[NUM_0]) +
3583         (static_cast<uint32_t>(fileData[NUM_1]) << NUM_8) +
3584         (static_cast<uint32_t>(fileData[NUM_2]) << NUM_16) +
3585         (static_cast<uint32_t>(fileData[NUM_3]) << NUM_24);
3586     if (magicVal == ASTC_MAGIC_ID) {
3587         unsigned int astcWidth = static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_X]) +
3588             (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_X + 1]) << NUM_8) +
3589             (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_X + NUM_2]) << NUM_16);
3590         unsigned int astcHeight = static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_Y]) +
3591             (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_Y + 1]) << NUM_8) +
3592             (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_Y + NUM_2]) << NUM_16);
3593         astcInfo.size.width = static_cast<int32_t>(astcWidth);
3594         astcInfo.size.height = static_cast<int32_t>(astcHeight);
3595         astcInfo.blockFootprint.width = fileData[ASTC_HEADER_BLOCK_X];
3596         astcInfo.blockFootprint.height = fileData[ASTC_HEADER_BLOCK_Y];
3597         if (astcInfo.blockFootprint.width != astcInfo.blockFootprint.height) {
3598             IMAGE_LOGE("[ImageSource]GetASTCInfo blockFootprint failed");
3599             return false;
3600         }
3601         return true;
3602     }
3603 #ifdef SUT_DECODE_ENABLE
3604     if (!g_sutDecSoManager.LoadSutDecSo() || g_sutDecSoManager.getTextureInfoFunc_ == nullptr) {
3605         IMAGE_LOGE("[ImageSource] SUT dec so dlopen failed or getTextureInfoFunc_ is nullptr!");
3606         return false;
3607     }
3608     uint32_t blockXY;
3609     uint32_t width;
3610     uint32_t height;
3611     if (g_sutDecSoManager.getTextureInfoFunc_(fileData, fileSize,
3612         width, height, blockXY)) {
3613         astcInfo.size.width = width;
3614         astcInfo.size.height = height;
3615         astcInfo.blockFootprint.width = blockXY;
3616         astcInfo.blockFootprint.height = blockXY;
3617         return true;
3618     }
3619 #endif
3620     return false;
3621 }
3622 
CreatePixelMapList(const DecodeOptions & opts,uint32_t & errorCode)3623 unique_ptr<vector<unique_ptr<PixelMap>>> ImageSource::CreatePixelMapList(const DecodeOptions &opts, uint32_t &errorCode)
3624 {
3625     ImageDataStatistics imageDataStatistics("[ImageSource]CreatePixelMapList.");
3626     DumpInputData();
3627     auto frameCount = GetFrameCount(errorCode);
3628     if (errorCode != SUCCESS) {
3629         IMAGE_LOGE("[ImageSource]CreatePixelMapList get frame count error.");
3630         return nullptr;
3631     }
3632 
3633     auto pixelMaps = std::make_unique<vector<unique_ptr<PixelMap>>>();
3634     for (uint32_t index = 0; index < frameCount; index++) {
3635         auto pixelMap = CreatePixelMap(index, opts, errorCode);
3636         if (errorCode != SUCCESS) {
3637             IMAGE_LOGE("[ImageSource]CreatePixelMapList create PixelMap error. index=%{public}u", index);
3638             return nullptr;
3639         }
3640         pixelMaps->push_back(std::move(pixelMap));
3641     }
3642 
3643     errorCode = SUCCESS;
3644 
3645     return pixelMaps;
3646 }
3647 
GetDelayTime(uint32_t & errorCode)3648 unique_ptr<vector<int32_t>> ImageSource::GetDelayTime(uint32_t &errorCode)
3649 {
3650     auto frameCount = GetFrameCount(errorCode);
3651     if (errorCode != SUCCESS) {
3652         IMAGE_LOGE("Failed to get frame count in GetDelayTime.");
3653         return nullptr;
3654     }
3655 
3656     auto delayTimes = std::make_unique<vector<int32_t>>();
3657     if (sourceInfo_.encodedFormat == "image/webp" && frameCount == 1) {
3658         errorCode = SUCCESS;
3659         return delayTimes;
3660     }
3661     for (uint32_t index = 0; index < frameCount; index++) {
3662         string delayTimeStr;
3663         errorCode = mainDecoder_->GetImagePropertyString(index, IMAGE_DELAY_TIME, delayTimeStr);
3664         if (errorCode != SUCCESS) {
3665             IMAGE_LOGE("Issue getting delay time in GetDelayTime. "
3666                 "Index: %{public}u",
3667                 index);
3668             return nullptr;
3669         }
3670         if (!IsNumericStr(delayTimeStr)) {
3671             IMAGE_LOGE("Delay time string is not numeric in GetDelayTime. "
3672                 "Delay time string: %{public}s",
3673                 delayTimeStr.c_str());
3674             return nullptr;
3675         }
3676         int delayTime = 0;
3677         if (!StrToInt(delayTimeStr, delayTime)) {
3678             IMAGE_LOGE("Failed to convert delay time string to int in GetDelayTime. "
3679                 "Delay time string: %{public}s",
3680                 delayTimeStr.c_str());
3681             return nullptr;
3682         }
3683         delayTimes->push_back(delayTime);
3684     }
3685 
3686     errorCode = SUCCESS;
3687 
3688     return delayTimes;
3689 }
3690 
GetDisposalType(uint32_t & errorCode)3691 unique_ptr<vector<int32_t>> ImageSource::GetDisposalType(uint32_t &errorCode)
3692 {
3693     auto frameCount = GetFrameCount(errorCode);
3694     if (errorCode != SUCCESS) {
3695         IMAGE_LOGE("[ImageSource]GetDisposalType get frame sum error.");
3696         return nullptr;
3697     }
3698 
3699     auto disposalTypes = std::make_unique<vector<int32_t>>();
3700     for (uint32_t index = 0; index < frameCount; index++) {
3701         int disposalType = 0;
3702         errorCode = mainDecoder_->GetImagePropertyInt(index, IMAGE_DISPOSAL_TYPE, disposalType);
3703         if (errorCode != SUCCESS) {
3704             IMAGE_LOGE("[ImageSource]GetDisposalType get delay time issue. index=%{public}u", index);
3705             return nullptr;
3706         }
3707         disposalTypes->push_back(disposalType);
3708     }
3709 
3710     errorCode = SUCCESS;
3711 
3712     return disposalTypes;
3713 }
3714 
GetLoopCount(uint32_t & errorCode)3715 int32_t ImageSource::GetLoopCount(uint32_t &errorCode)
3716 {
3717     (void)GetFrameCount(errorCode);
3718     if (errorCode != SUCCESS || mainDecoder_ == nullptr) {
3719         IMAGE_LOGE("[ImageSource]GetLoopCount get frame sum error.");
3720         return errorCode;
3721     }
3722 
3723     int32_t loopCount = 0;
3724     const string IMAGE_LOOP_COUNT = "GIFLoopCount";
3725     errorCode = mainDecoder_->GetImagePropertyInt(0, IMAGE_LOOP_COUNT, loopCount);
3726     if (errorCode != SUCCESS) {
3727         IMAGE_LOGE("[ImageSource]GetLoopCount get loop count issue. errorCode=%{public}u", errorCode);
3728         return errorCode;
3729     }
3730 
3731     errorCode = SUCCESS;
3732 
3733     return loopCount;
3734 }
3735 
GetFrameCount(uint32_t & errorCode)3736 uint32_t ImageSource::GetFrameCount(uint32_t &errorCode)
3737 {
3738     uint32_t frameCount = GetSourceInfo(errorCode).topLevelImageNum;
3739     if (errorCode != SUCCESS) {
3740         IMAGE_LOGE("[ImageSource]GetFrameCount get source info error.");
3741         return 0;
3742     }
3743 
3744     if (InitMainDecoder() != SUCCESS) {
3745         IMAGE_LOGE("[ImageSource]GetFrameCount image decode plugin is null.");
3746         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
3747         return 0;
3748     }
3749 
3750     return frameCount;
3751 }
3752 
SetSource(const std::string & source)3753 void ImageSource::SetSource(const std::string &source)
3754 {
3755     source_ = source;
3756 }
3757 
DumpInputData(const std::string & fileSuffix)3758 void ImageSource::DumpInputData(const std::string &fileSuffix)
3759 {
3760     if (!ImageSystemProperties::GetDumpImageEnabled()) {
3761         return;
3762     }
3763 
3764     if (sourceStreamPtr_ == nullptr) {
3765         IMAGE_LOGI("ImageSource::DumpInputData failed, streamPtr is null");
3766         return;
3767     }
3768 
3769     uint8_t *data = sourceStreamPtr_->GetDataPtr();
3770     size_t size = sourceStreamPtr_->GetStreamSize();
3771 
3772     ImageUtils::DumpDataIfDumpEnabled(reinterpret_cast<const char *>(data), size, fileSuffix, imageId_);
3773 }
3774 
3775 #ifdef IMAGE_PURGEABLE_PIXELMAP
GetSourceSize() const3776 size_t ImageSource::GetSourceSize() const
3777 {
3778     return sourceStreamPtr_ ? sourceStreamPtr_->GetStreamSize() : 0;
3779 }
3780 #endif
3781 
IsSupportGenAstc()3782 bool ImageSource::IsSupportGenAstc()
3783 {
3784     return ImageSystemProperties::GetMediaLibraryAstcEnabled();
3785 }
3786 
GetExtendedCodecMimeType(AbsImageDecoder * decoder)3787 static string GetExtendedCodecMimeType(AbsImageDecoder* decoder)
3788 {
3789     const static string ENCODED_FORMAT_KEY = "EncodedFormat";
3790     string format;
3791     if (decoder != nullptr && decoder->GetImagePropertyString(FIRST_FRAME, ENCODED_FORMAT_KEY, format) == SUCCESS) {
3792         return format;
3793     }
3794     return string();
3795 }
3796 
GetScaleSize(ImageInfo info,DecodeOptions opts)3797 static float GetScaleSize(ImageInfo info, DecodeOptions opts)
3798 {
3799     if (info.size.width == 0 || info.size.height == 0) {
3800         return 1.0;
3801     }
3802     float scale = max(static_cast<float>(opts.desiredSize.width) / info.size.width,
3803                       static_cast<float>(opts.desiredSize.height) / info.size.height);
3804     return scale;
3805 }
3806 
GetByteCount(const DecodeContext & context,uint32_t surfaceBufferSize)3807 static uint32_t GetByteCount(const DecodeContext& context, uint32_t surfaceBufferSize)
3808 {
3809     uint32_t byteCount = surfaceBufferSize;
3810     ImageInfo info;
3811     switch (context.info.pixelFormat) {
3812         case PixelFormat::RGBA_8888:
3813         case PixelFormat::BGRA_8888:
3814         case PixelFormat::NV12:
3815         case PixelFormat::NV21:
3816         case PixelFormat::RGBA_1010102:
3817         case PixelFormat::YCBCR_P010:
3818             info.pixelFormat = context.info.pixelFormat;
3819             break;
3820         default:
3821             IMAGE_LOGE("[ImageSource] GetByteCount pixelFormat %{public}u error", context.info.pixelFormat);
3822             return byteCount;
3823     }
3824     info.size.width = context.info.size.width;
3825     info.size.height = context.info.size.height;
3826     byteCount = static_cast<uint32_t>(PixelMap::GetAllocatedByteCount(info));
3827     return byteCount;
3828 }
3829 
3830 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
DecomposeImage(sptr<SurfaceBuffer> & hdr,sptr<SurfaceBuffer> & sdr)3831 static bool DecomposeImage(sptr<SurfaceBuffer>& hdr, sptr<SurfaceBuffer>& sdr)
3832 {
3833     ImageTrace imageTrace("ImageSource decomposeImage");
3834     VpeUtils::SetSbMetadataType(hdr, HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_SINGLE);
3835     VpeUtils::SetSbMetadataType(sdr, HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_DUAL);
3836     VpeUtils::SetSbColorSpaceType(sdr, HDI::Display::Graphic::Common::V1_0::CM_P3_FULL);
3837     std::unique_ptr<VpeUtils> utils = std::make_unique<VpeUtils>();
3838     int32_t res = utils->ColorSpaceConverterImageProcess(hdr, sdr);
3839     bool cond = res != VPE_ERROR_OK || sdr == nullptr;
3840     CHECK_ERROR_RETURN_RET(cond, false);
3841     return true;
3842 }
3843 
SetContext(DecodeContext & context,sptr<SurfaceBuffer> & sb,void * fd,uint32_t format)3844 static void SetContext(DecodeContext& context, sptr<SurfaceBuffer>& sb, void* fd, uint32_t format)
3845 {
3846     context.allocatorType = AllocatorType::DMA_ALLOC;
3847     context.freeFunc = nullptr;
3848     context.pixelsBuffer.buffer = static_cast<uint8_t*>(sb->GetVirAddr());
3849     context.pixelsBuffer.bufferSize = GetByteCount(context, sb->GetSize());
3850     context.pixelsBuffer.context = fd;
3851     context.info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
3852     if (format == GRAPHIC_PIXEL_FMT_RGBA_1010102) {
3853         context.pixelFormat = PixelFormat::RGBA_1010102;
3854         context.info.pixelFormat = PixelFormat::RGBA_1010102;
3855         context.grColorSpaceName = ColorManager::BT2020_HLG;
3856     } else if (format == GRAPHIC_PIXEL_FMT_RGBA_8888) {
3857         context.pixelFormat = PixelFormat::RGBA_8888;
3858         context.info.pixelFormat = PixelFormat::RGBA_8888;
3859         context.grColorSpaceName = ColorManager::DISPLAY_P3;
3860     } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
3861         context.pixelFormat = PixelFormat::NV12;
3862         context.info.pixelFormat = PixelFormat::NV12;
3863         context.grColorSpaceName = ColorManager::DISPLAY_P3;
3864     } else if (format == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
3865         context.pixelFormat = PixelFormat::NV21;
3866         context.info.pixelFormat = PixelFormat::NV21;
3867         context.grColorSpaceName = ColorManager::DISPLAY_P3;
3868     } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
3869         context.pixelFormat = PixelFormat::YCBCR_P010;
3870         context.info.pixelFormat = PixelFormat::YCBCR_P010;
3871         context.grColorSpaceName = ColorManager::BT2020_HLG;
3872     }
3873 }
3874 
AllocSurfaceBuffer(DecodeContext & context,uint32_t format)3875 static uint32_t AllocSurfaceBuffer(DecodeContext &context, uint32_t format)
3876 {
3877 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
3878     IMAGE_LOGE("UnSupport dma mem alloc");
3879     return ERR_IMAGE_DATA_UNSUPPORT;
3880 #else
3881     sptr<SurfaceBuffer> sb = SurfaceBuffer::Create();
3882     IMAGE_LOGD("[ImageSource]AllocBufferForContext requestConfig, sizeInfo.width:%{public}u,height:%{public}u.",
3883                context.info.size.width, context.info.size.height);
3884     BufferRequestConfig requestConfig = {
3885         .width = context.info.size.width,
3886         .height = context.info.size.height,
3887         .strideAlignment = 0x8, // set 0x8 as default value to alloc SurfaceBufferImpl
3888         .format = format,
3889         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
3890         .timeout = 0,
3891     };
3892     GSError ret = sb->Alloc(requestConfig);
3893     if (ret != GSERROR_OK) {
3894         IMAGE_LOGE("SurfaceBuffer Alloc failed, %{public}s", GSErrorStr(ret).c_str());
3895         return ERR_DMA_NOT_EXIST;
3896     }
3897     void* nativeBuffer = sb.GetRefPtr();
3898     int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer);
3899     if (err != OHOS::GSERROR_OK) {
3900         IMAGE_LOGE("NativeBufferReference failed");
3901         return ERR_DMA_DATA_ABNORMAL;
3902     }
3903     SetContext(context, sb, nativeBuffer, format);
3904     return SUCCESS;
3905 #endif
3906 }
3907 
ConvertColorSpaceType(ColorManager::ColorSpaceName colorSpace,bool base)3908 CM_ColorSpaceType ImageSource::ConvertColorSpaceType(ColorManager::ColorSpaceName colorSpace, bool base)
3909 {
3910     switch (colorSpace) {
3911         case ColorManager::ColorSpaceName::SRGB :
3912             return CM_SRGB_FULL;
3913         case ColorManager::ColorSpaceName::SRGB_LIMIT :
3914             return CM_SRGB_LIMIT;
3915         case ColorManager::ColorSpaceName::DISPLAY_P3 :
3916             return CM_P3_FULL;
3917         case ColorManager::ColorSpaceName::DISPLAY_P3_LIMIT :
3918             return CM_P3_LIMIT;
3919         case ColorManager::ColorSpaceName::BT2020 :
3920         case ColorManager::ColorSpaceName::BT2020_HLG :
3921             return CM_BT2020_HLG_FULL;
3922         case ColorManager::ColorSpaceName::BT2020_HLG_LIMIT :
3923             return CM_BT2020_HLG_LIMIT;
3924         case ColorManager::ColorSpaceName::BT2020_PQ :
3925             return CM_BT2020_PQ_FULL;
3926         case ColorManager::ColorSpaceName::BT2020_PQ_LIMIT :
3927             return CM_BT2020_PQ_LIMIT;
3928         default:
3929             return base ? CM_P3_FULL : CM_BT2020_HLG_FULL;
3930     }
3931     return base ? CM_P3_FULL : CM_BT2020_HLG_FULL;
3932 }
3933 
ConvertColorSpaceName(CM_ColorSpaceType colorSpace,bool base)3934 static ColorManager::ColorSpaceName ConvertColorSpaceName(CM_ColorSpaceType colorSpace, bool base)
3935 {
3936     switch (colorSpace) {
3937         case CM_SRGB_FULL :
3938             return ColorManager::SRGB;
3939         case CM_SRGB_LIMIT :
3940             return ColorManager::SRGB_LIMIT;
3941         case CM_P3_FULL :
3942             return ColorManager::DISPLAY_P3;
3943         case CM_P3_LIMIT :
3944             return ColorManager::DISPLAY_P3_LIMIT;
3945         case CM_BT2020_HLG_FULL :
3946             return ColorManager::BT2020_HLG;
3947         case CM_BT2020_HLG_LIMIT :
3948             return ColorManager::BT2020_HLG_LIMIT;
3949         case CM_BT2020_PQ_FULL :
3950             return ColorManager::BT2020_PQ;
3951         case CM_BT2020_PQ_LIMIT :
3952             return ColorManager::BT2020_PQ_LIMIT;
3953         default:
3954             return base ? ColorManager::DISPLAY_P3 : ColorManager::BT2020_HLG;
3955     }
3956     return base ? ColorManager::DISPLAY_P3 : ColorManager::BT2020_HLG;
3957 }
3958 #endif
3959 
SetDmaContextYuvInfo(DecodeContext & context)3960 void ImageSource::SetDmaContextYuvInfo(DecodeContext& context)
3961 {
3962 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
3963     IMAGE_LOGD("UnSupport SetContextYuvInfo");
3964     return;
3965 #else
3966     if (context.allocatorType != AllocatorType::DMA_ALLOC) {
3967         IMAGE_LOGD("SetDmaContextYuvInfo allocatorType is not dma");
3968         return;
3969     }
3970     PixelFormat format = context.info.pixelFormat;
3971     if (!IsYuvFormat(format)) {
3972         IMAGE_LOGI("SetDmaContextYuvInfo format is not yuv");
3973         return;
3974     }
3975     SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(context.pixelsBuffer.context);
3976     if (surfaceBuffer == nullptr) {
3977         IMAGE_LOGE("SetDmaContextYuvInfo surfacebuffer is nullptr");
3978         return;
3979     }
3980     OH_NativeBuffer_Planes *planes = nullptr;
3981     GSError retVal = surfaceBuffer->GetPlanesInfo(reinterpret_cast<void**>(&planes));
3982     if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
3983         IMAGE_LOGE("SetDmaContextYuvInfo, GetPlanesInfo failed retVal:%{public}d", retVal);
3984         return;
3985     }
3986     const OH_NativeBuffer_Plane &planeY = planes->planes[0];
3987     const OH_NativeBuffer_Plane &planeUV =
3988         planes->planes[(format == PixelFormat::NV21 || format == PixelFormat::YCRCB_P010) ? NUM_2 : NUM_1];
3989     if (format == PixelFormat::YCRCB_P010 || format == PixelFormat::YCBCR_P010) {
3990         context.yuvInfo.yStride = planeY.columnStride / NUM_2;
3991         context.yuvInfo.uvStride = planeUV.columnStride / NUM_2;
3992         context.yuvInfo.yOffset = planeY.offset / NUM_2;
3993         context.yuvInfo.uvOffset = planeUV.offset / NUM_2;
3994     } else {
3995         context.yuvInfo.yStride = planeY.columnStride;
3996         context.yuvInfo.uvStride = planeUV.columnStride;
3997         context.yuvInfo.yOffset = planeY.offset;
3998         context.yuvInfo.uvOffset = planeUV.offset;
3999     }
4000     context.yuvInfo.imageSize = context.info.size;
4001     context.yuvInfo.yWidth = static_cast<uint32_t>(context.info.size.width);
4002     context.yuvInfo.yHeight = static_cast<uint32_t>(context.info.size.height);
4003     context.yuvInfo.uvWidth = static_cast<uint32_t>((context.info.size.width + 1) / NUM_2);
4004     context.yuvInfo.uvHeight = static_cast<uint32_t>((context.info.size.height + 1) / NUM_2);
4005     IMAGE_LOGD("SetDmaContextYuvInfo format:%{public}d, yStride:%{public}d, uvStride:%{public}d, yOffset:%{public}d,"
4006         "uvOffset:%{public}d, imageSize:%{public}d-%{public}d", format, context.yuvInfo.yStride,
4007         context.yuvInfo.uvStride, context.yuvInfo.yOffset, context.yuvInfo.uvOffset,
4008         context.yuvInfo.imageSize.width, context.yuvInfo.imageSize.height);
4009 #endif
4010 }
4011 
HandleSingleHdrImage(ImageHdrType decodedHdrType,DecodeContext & context,ImagePlugin::PlImageInfo & plInfo)4012 DecodeContext ImageSource::HandleSingleHdrImage(ImageHdrType decodedHdrType,
4013     DecodeContext& context, ImagePlugin::PlImageInfo& plInfo)
4014 {
4015     SetDmaContextYuvInfo(context);
4016 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
4017     IMAGE_LOGE("UnSupport HandleSingleHdrImage");
4018     return context;
4019 #else
4020     bool cond = context.allocatorType != AllocatorType::DMA_ALLOC;
4021     CHECK_ERROR_RETURN_RET(cond, context);
4022     sptr<SurfaceBuffer> hdrSptr(reinterpret_cast<SurfaceBuffer*>(context.pixelsBuffer.context));
4023     HdrMetadata metadata = mainDecoder_->GetHdrMetadata(decodedHdrType);
4024     CM_ColorSpaceType baseCmColor = ConvertColorSpaceType(context.grColorSpaceName, true);
4025     VpeUtils::SetSurfaceBufferInfo(hdrSptr, false, decodedHdrType, baseCmColor, metadata);
4026     if (opts_.desiredDynamicRange == DecodeDynamicRange::SDR) {
4027         DecodeContext sdrCtx;
4028         sdrCtx.info.size.width = plInfo.size.width;
4029         sdrCtx.info.size.height = plInfo.size.height;
4030         sdrCtx.hdrType = ImageHdrType::SDR;
4031         sdrCtx.outInfo.size = sdrCtx.info.size;
4032         auto formatSearch = SINGLE_HDR_CONVERT_FORMAT_MAP.find(opts_.desiredPixelFormat);
4033         auto allocFormat =
4034             (formatSearch != SINGLE_HDR_CONVERT_FORMAT_MAP.end()) ? formatSearch->second : GRAPHIC_PIXEL_FMT_RGBA_8888;
4035         uint32_t res = AllocSurfaceBuffer(sdrCtx, allocFormat);
4036         cond = res != SUCCESS;
4037         CHECK_INFO_RETURN_RET_LOG(cond, context, "single hdr convert to sdr,alloc surfacebuffer failed");
4038         sptr<SurfaceBuffer> sdr(reinterpret_cast<SurfaceBuffer*>(sdrCtx.pixelsBuffer.context));
4039         if (DecomposeImage(hdrSptr, sdr)) {
4040             FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer);
4041             plInfo = sdrCtx.info;
4042             SetDmaContextYuvInfo(sdrCtx);
4043             return sdrCtx;
4044         }
4045         FreeContextBuffer(sdrCtx.freeFunc, sdrCtx.allocatorType, sdrCtx.pixelsBuffer);
4046     }
4047     return context;
4048 #endif
4049 }
4050 
HandleDualHdrImage(ImageHdrType decodedHdrType,ImageInfo info,DecodeContext & context,ImagePlugin::PlImageInfo & plInfo)4051 DecodeContext ImageSource::HandleDualHdrImage(ImageHdrType decodedHdrType, ImageInfo info,
4052     DecodeContext& context, ImagePlugin::PlImageInfo& plInfo)
4053 {
4054     DecodeContext hdrContext;
4055     hdrContext.hdrType = decodedHdrType;
4056     hdrContext.info.size = plInfo.size;
4057     hdrContext.allocatorType = AllocatorType::DMA_ALLOC;
4058     float scale = GetScaleSize(info, opts_);
4059     if (decodedHdrType > ImageHdrType::SDR && ApplyGainMap(decodedHdrType, context, hdrContext, scale)) {
4060         FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer);
4061         plInfo = hdrContext.info;
4062         hdrContext.outInfo.size = hdrContext.info.size;
4063         return hdrContext;
4064     }
4065     context.hdrType = ImageHdrType::SDR;
4066     return context;
4067 }
4068 
DecodeImageDataToContext(uint32_t index,ImageInfo info,ImagePlugin::PlImageInfo & plInfo,uint32_t & errorCode)4069 DecodeContext ImageSource::DecodeImageDataToContext(uint32_t index, ImageInfo info, ImagePlugin::PlImageInfo& plInfo,
4070                                                     uint32_t& errorCode)
4071 {
4072     DecodeContext context = InitDecodeContext(opts_, info, preference_, hasDesiredSizeOptions, plInfo);
4073     ImageHdrType decodedHdrType = context.hdrType;
4074     context.grColorSpaceName = mainDecoder_->GetPixelMapColorSpace().GetColorSpaceName();
4075     errorCode = mainDecoder_->Decode(index, context);
4076     if (plInfo.size.width != context.outInfo.size.width || plInfo.size.height != context.outInfo.size.height) {
4077         // hardware decode success, update plInfo.size
4078         IMAGE_LOGI("hardware decode success, soft decode dstInfo:(%{public}u, %{public}u), use hardware dstInfo:"
4079             "(%{public}u, %{public}u)", plInfo.size.width, plInfo.size.height, context.outInfo.size.width,
4080             context.outInfo.size.height);
4081         plInfo.size = context.outInfo.size;
4082     }
4083     context.info = plInfo;
4084     ninePatchInfo_.ninePatch = context.ninePatchContext.ninePatch;
4085     ninePatchInfo_.patchSize = context.ninePatchContext.patchSize;
4086     if (errorCode != SUCCESS) {
4087         FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer);
4088         return context;
4089     }
4090     if (IsSingleHdrImage(decodedHdrType)) {
4091         return HandleSingleHdrImage(decodedHdrType, context, plInfo);
4092     }
4093     if (IsDualHdrImage(decodedHdrType)) {
4094         return HandleDualHdrImage(decodedHdrType, info, context, plInfo);
4095     }
4096     return context;
4097 }
4098 
SetGainMapDecodeOption(std::unique_ptr<AbsImageDecoder> & decoder,PlImageInfo & plInfo,float scale)4099 uint32_t ImageSource::SetGainMapDecodeOption(std::unique_ptr<AbsImageDecoder>& decoder, PlImageInfo& plInfo,
4100                                              float scale)
4101 {
4102     ImageInfo info;
4103     Size size;
4104     uint32_t errorCode = decoder->GetImageSize(FIRST_FRAME, size);
4105     info.size.width = size.width;
4106     info.size.height = size.height;
4107     if (errorCode != SUCCESS || !IsSizeVailed({size.width, size.height})) {
4108         errorCode = ERR_IMAGE_DATA_ABNORMAL;
4109         return errorCode;
4110     }
4111     Size wantSize = info.size;
4112     if (scale > 0 && scale < 1.0) {
4113         wantSize.width = info.size.width * scale;
4114         wantSize.height = info.size.height * scale;
4115     }
4116     DecodeOptions opts;
4117     TransformSizeWithDensity(info.size, sourceInfo_.baseDensity, wantSize, opts_.fitDensity, opts.desiredSize);
4118     PixelDecodeOptions plOptions;
4119     CopyOptionsToPlugin(opts, plOptions);
4120     plOptions.desiredPixelFormat = PixelFormat::RGBA_8888;
4121     errorCode = decoder->SetDecodeOptions(FIRST_FRAME, plOptions, plInfo);
4122     return errorCode;
4123 }
4124 
GetStreamData(std::unique_ptr<SourceStream> & sourceStream,uint8_t * streamBuffer,uint32_t streamSize)4125 bool GetStreamData(std::unique_ptr<SourceStream>& sourceStream, uint8_t* streamBuffer, uint32_t streamSize)
4126 {
4127     if (streamBuffer == nullptr) {
4128         IMAGE_LOGE("GetStreamData streamBuffer is nullptr");
4129         return false;
4130     }
4131     uint32_t readSize = 0;
4132     uint32_t savedPosition = sourceStream->Tell();
4133     sourceStream->Seek(0);
4134     bool result = sourceStream->Read(streamSize, streamBuffer, streamSize, readSize);
4135     sourceStream->Seek(savedPosition);
4136     if (!result || (readSize != streamSize)) {
4137         IMAGE_LOGE("sourceStream read data failed");
4138         return false;
4139     }
4140     return true;
4141 }
4142 
DecodeJpegGainMap(ImageHdrType hdrType,float scale,DecodeContext & gainMapCtx,HdrMetadata & metadata)4143 bool ImageSource::DecodeJpegGainMap(ImageHdrType hdrType, float scale, DecodeContext& gainMapCtx, HdrMetadata& metadata)
4144 {
4145     ImageTrace imageTrace("ImageSource::DecodeJpegGainMap hdrType:%d, scale:%d", hdrType, scale);
4146     uint32_t gainMapOffset = mainDecoder_->GetGainMapOffset();
4147     uint32_t streamSize = sourceStreamPtr_->GetStreamSize();
4148     if (gainMapOffset == 0 || gainMapOffset > streamSize || streamSize == 0) {
4149         return false;
4150     }
4151     uint8_t* streamBuffer = sourceStreamPtr_->GetDataPtr();
4152     if (sourceStreamPtr_->GetStreamType() != ImagePlugin::BUFFER_SOURCE_TYPE) {
4153         streamBuffer = new (std::nothrow) uint8_t[streamSize];
4154         if (!GetStreamData(sourceStreamPtr_, streamBuffer, streamSize)) {
4155             delete[] streamBuffer;
4156             return false;
4157         }
4158     }
4159     std::unique_ptr<InputDataStream> gainMapStream =
4160         BufferSourceStream::CreateSourceStream((streamBuffer + gainMapOffset), (streamSize - gainMapOffset));
4161     if (sourceStreamPtr_->GetStreamType() != ImagePlugin::BUFFER_SOURCE_TYPE) {
4162         delete[] streamBuffer;
4163     }
4164     if (gainMapStream == nullptr) {
4165         IMAGE_LOGE("[ImageSource] create gainmap stream fail, gainmap offset is %{public}d", gainMapOffset);
4166         return false;
4167     }
4168     uint32_t errorCode;
4169     jpegGainmapDecoder_ = std::unique_ptr<AbsImageDecoder>(
4170         DoCreateDecoder(InnerFormat::IMAGE_EXTENDED_CODEC, pluginServer_, *gainMapStream, errorCode));
4171     if (jpegGainmapDecoder_ == nullptr) {
4172         IMAGE_LOGE("[ImageSource] create gainmap decoder fail, gainmap offset is %{public}d", gainMapOffset);
4173         return false;
4174     }
4175     PlImageInfo gainMapInfo;
4176     errorCode = SetGainMapDecodeOption(jpegGainmapDecoder_, gainMapInfo, scale);
4177     if (errorCode != SUCCESS) {
4178         return false;
4179     }
4180     gainMapCtx.allocatorType = AllocatorType::DMA_ALLOC;
4181     errorCode = jpegGainmapDecoder_->Decode(FIRST_FRAME, gainMapCtx);
4182     if (gainMapInfo.size.width != gainMapCtx.outInfo.size.width ||
4183         gainMapInfo.size.height != gainMapCtx.outInfo.size.height) {
4184         // hardware decode success, update gainMapInfo.size
4185         gainMapInfo.size = gainMapCtx.outInfo.size;
4186     }
4187     gainMapCtx.info = gainMapInfo;
4188     if (errorCode != SUCCESS) {
4189         FreeContextBuffer(gainMapCtx.freeFunc, gainMapCtx.allocatorType, gainMapCtx.pixelsBuffer);
4190         return false;
4191     }
4192     metadata = jpegGainmapDecoder_->GetHdrMetadata(hdrType);
4193     return true;
4194 }
4195 
ApplyGainMap(ImageHdrType hdrType,DecodeContext & baseCtx,DecodeContext & hdrCtx,float scale)4196 bool ImageSource::ApplyGainMap(ImageHdrType hdrType, DecodeContext& baseCtx, DecodeContext& hdrCtx, float scale)
4197 {
4198     string format = GetExtendedCodecMimeType(mainDecoder_.get());
4199     if (format != IMAGE_JPEG_FORMAT && format != IMAGE_HEIF_FORMAT && format != IMAGE_HEIC_FORMAT) {
4200         return false;
4201     }
4202     DecodeContext gainMapCtx;
4203     HdrMetadata metadata;
4204     if (format == IMAGE_HEIF_FORMAT || format == IMAGE_HEIC_FORMAT) {
4205         ImageTrace imageTrace("ImageSource decode heif gainmap hdrType:%d, scale:%d", hdrType, scale);
4206         bool cond = !mainDecoder_->DecodeHeifGainMap(gainMapCtx);
4207         CHECK_INFO_RETURN_RET_LOG(cond, false, "[ImageSource] heif get gainmap failed");
4208         metadata = mainDecoder_->GetHdrMetadata(hdrType);
4209     } else if (!DecodeJpegGainMap(hdrType, scale, gainMapCtx, metadata)) {
4210         IMAGE_LOGI("[ImageSource] jpeg get gainmap failed");
4211         return false;
4212     }
4213     IMAGE_LOGD("get hdr metadata, extend flag is %{public}d, static size is %{public}zu,"
4214         "dynamic metadata size is %{public}zu",
4215         metadata.extendMetaFlag, metadata.staticMetadata.size(), metadata.dynamicMetadata.size());
4216     bool result = ComposeHdrImage(hdrType, baseCtx, gainMapCtx, hdrCtx, metadata);
4217     FreeContextBuffer(gainMapCtx.freeFunc, gainMapCtx.allocatorType, gainMapCtx.pixelsBuffer);
4218     return result;
4219 }
4220 
4221 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
SetVividMetaColor(HdrMetadata & metadata,CM_ColorSpaceType base,CM_ColorSpaceType gainmap,CM_ColorSpaceType hdr)4222 void ImageSource::SetVividMetaColor(HdrMetadata& metadata,
4223     CM_ColorSpaceType base, CM_ColorSpaceType gainmap, CM_ColorSpaceType hdr)
4224 {
4225     metadata.extendMeta.baseColorMeta.baseColorPrimary = base & 0xFF;
4226     metadata.extendMeta.gainmapColorMeta.enhanceDataColorPrimary = gainmap & 0xFF;
4227     metadata.extendMeta.gainmapColorMeta.combineColorPrimary = gainmap & 0xFF;
4228     metadata.extendMeta.gainmapColorMeta.alternateColorPrimary = hdr & 0xFF;
4229 }
4230 
GetHdrMediaType(HdrMetadata & metadata)4231 static CM_HDR_Metadata_Type GetHdrMediaType(HdrMetadata& metadata)
4232 {
4233     CM_HDR_Metadata_Type hdrMetadataType = static_cast<CM_HDR_Metadata_Type>(metadata.hdrMetadataType);
4234     switch (hdrMetadataType) {
4235         case CM_VIDEO_HLG:
4236         case CM_VIDEO_HDR10:
4237         case CM_VIDEO_HDR_VIVID:
4238             return CM_IMAGE_HDR_VIVID_SINGLE;
4239         default:
4240             break;
4241     }
4242     return hdrMetadataType;
4243 }
4244 
AllocHdrSurfaceBuffer(DecodeContext & context,ImageHdrType hdrType,CM_ColorSpaceType color)4245 static uint32_t AllocHdrSurfaceBuffer(DecodeContext& context, ImageHdrType hdrType, CM_ColorSpaceType color)
4246 {
4247 #if defined(_WIN32) || defined(_APPLE) || defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
4248     IMAGE_LOGE("UnSupport dma mem alloc");
4249     return ERR_IMAGE_DATA_UNSUPPORT;
4250 #else
4251     sptr<SurfaceBuffer> sb = SurfaceBuffer::Create();
4252     auto hdrPixelFormat = GRAPHIC_PIXEL_FMT_RGBA_1010102;
4253     if (context.photoDesiredPixelFormat == PixelFormat::YCBCR_P010) {
4254         hdrPixelFormat = GRAPHIC_PIXEL_FMT_YCBCR_P010;
4255     }
4256     BufferRequestConfig requestConfig = {
4257         .width = context.info.size.width,
4258         .height = context.info.size.height,
4259         .strideAlignment = context.info.size.width,
4260         .format = hdrPixelFormat,
4261         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
4262         .timeout = 0,
4263     };
4264     GSError ret = sb->Alloc(requestConfig);
4265     if (ret != GSERROR_OK) {
4266         return ERR_DMA_NOT_EXIST;
4267     }
4268     void* nativeBuffer = sb.GetRefPtr();
4269     int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer);
4270     if (err != OHOS::GSERROR_OK) {
4271         return ERR_DMA_DATA_ABNORMAL;
4272     }
4273     SetContext(context, sb, nativeBuffer, hdrPixelFormat);
4274     context.grColorSpaceName = ConvertColorSpaceName(color, false);
4275     CM_HDR_Metadata_Type type;
4276     if (hdrType == ImageHdrType::HDR_VIVID_DUAL || hdrType == ImageHdrType::HDR_CUVA) {
4277         type = CM_IMAGE_HDR_VIVID_SINGLE;
4278     } else if (hdrType == ImageHdrType::HDR_ISO_DUAL) {
4279         type = CM_IMAGE_HDR_ISO_SINGLE;
4280     }
4281     VpeUtils::SetSbMetadataType(sb, type);
4282     VpeUtils::SetSbColorSpaceType(sb, color);
4283     return SUCCESS;
4284 #endif
4285 }
4286 #endif
4287 
ApplyMemoryForHdr(DecodeContext & hdrCtx,CM_ColorSpaceType hdrCmColor,ImageHdrType hdrType)4288 void ImageSource::ApplyMemoryForHdr(DecodeContext& hdrCtx, CM_ColorSpaceType hdrCmColor, ImageHdrType hdrType)
4289 {
4290 #if !defined(CROSS_PLATFORM)
4291     hdrCtx.grColorSpaceName = ConvertColorSpaceName(hdrCmColor, false);
4292     CM_HDR_Metadata_Type type;
4293     if (hdrType == ImageHdrType::HDR_VIVID_DUAL || hdrType == ImageHdrType::HDR_CUVA) {
4294         type = CM_IMAGE_HDR_VIVID_SINGLE;
4295     } else if (hdrType == ImageHdrType::HDR_ISO_DUAL) {
4296         type = CM_IMAGE_HDR_ISO_SINGLE;
4297     }
4298     sptr<SurfaceBuffer> surfaceBuf(reinterpret_cast<SurfaceBuffer*>(opts_.reusePixelmap->GetFd()));
4299     VpeUtils::SetSbMetadataType(surfaceBuf, type);
4300     VpeUtils::SetSbColorSpaceType(surfaceBuf, hdrCmColor);
4301 #endif
4302 }
4303 
ComposeHdrImage(ImageHdrType hdrType,DecodeContext & baseCtx,DecodeContext & gainMapCtx,DecodeContext & hdrCtx,HdrMetadata metadata)4304 bool ImageSource::ComposeHdrImage(ImageHdrType hdrType, DecodeContext& baseCtx, DecodeContext& gainMapCtx,
4305                                   DecodeContext& hdrCtx, HdrMetadata metadata)
4306 {
4307 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
4308     IMAGE_LOGE("unsupport hdr");
4309     return false;
4310 #else
4311     ImageTrace imageTrace("ImageSource::ComposeHdrImage hdr type is %d", hdrType);
4312     if (baseCtx.allocatorType != AllocatorType::DMA_ALLOC || gainMapCtx.allocatorType != AllocatorType::DMA_ALLOC) {
4313         return false;
4314     }
4315     CM_ColorSpaceType baseCmColor = ConvertColorSpaceType(baseCtx.grColorSpaceName, true);
4316     // base image
4317     sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(baseCtx.pixelsBuffer.context));
4318     VpeUtils::SetSurfaceBufferInfo(baseSptr, false, hdrType, baseCmColor, metadata);
4319     // gainmap image
4320     sptr<SurfaceBuffer> gainmapSptr(reinterpret_cast<SurfaceBuffer*>(gainMapCtx.pixelsBuffer.context));
4321     CM_ColorSpaceType hdrCmColor = CM_BT2020_HLG_FULL;
4322     CM_ColorSpaceType gainmapCmColor = metadata.extendMeta.metaISO.useBaseColorFlag == 0x01 ? baseCmColor : hdrCmColor;
4323     IMAGE_LOGD("ComposeHdrImage color flag = %{public}d, gainmapChannelNum = %{public}d",
4324         metadata.extendMeta.metaISO.useBaseColorFlag, metadata.extendMeta.metaISO.gainmapChannelNum);
4325     SetVividMetaColor(metadata, baseCmColor, gainmapCmColor, hdrCmColor);
4326     VpeUtils::SetSurfaceBufferInfo(gainmapSptr, true, hdrType, gainmapCmColor, metadata);
4327     // videoHdrImage special process
4328     CM_HDR_Metadata_Type videoToimageHdrType = GetHdrMediaType(metadata);
4329     bool isVideoMetaDataType = videoToimageHdrType == CM_IMAGE_HDR_VIVID_SINGLE;
4330     if (isVideoMetaDataType) {
4331         VpeUtils::SetSbMetadataType(gainmapSptr, videoToimageHdrType);
4332     }
4333     // hdr image
4334 
4335     if (ImageUtils::IsHdrPixelMapReuseSuccess(hdrCtx, hdrCtx.info.size.width, hdrCtx.info.size.height,
4336         opts_.reusePixelmap)) {
4337         ApplyMemoryForHdr(hdrCtx, hdrCmColor, hdrType);
4338         IMAGE_LOGI("HDR reusePixelmap success");
4339     } else {
4340         uint32_t errorCode = AllocHdrSurfaceBuffer(hdrCtx, hdrType, hdrCmColor);
4341         bool cond = (errorCode != SUCCESS);
4342         CHECK_ERROR_RETURN_RET_LOG(cond, false, "HDR SurfaceBuffer Alloc failed, %{public}d", errorCode);
4343     }
4344     sptr<SurfaceBuffer> hdrSptr(reinterpret_cast<SurfaceBuffer*>(hdrCtx.pixelsBuffer.context));
4345     VpeSurfaceBuffers buffers = {
4346         .sdr = baseSptr,
4347         .gainmap = gainmapSptr,
4348         .hdr = hdrSptr,
4349     };
4350     std::unique_ptr<VpeUtils> utils = std::make_unique<VpeUtils>();
4351     bool legacy = hdrType == ImageHdrType::HDR_CUVA;
4352     int32_t res = utils->ColorSpaceConverterComposeImage(buffers, legacy);
4353     if (res != VPE_ERROR_OK) {
4354         IMAGE_LOGI("[ImageSource] composeImage failed");
4355         FreeContextBuffer(hdrCtx.freeFunc, hdrCtx.allocatorType, hdrCtx.pixelsBuffer);
4356         return false;
4357     }
4358     SetDmaContextYuvInfo(hdrCtx);
4359     if (isVideoMetaDataType) {
4360         VpeUtils::SetSbMetadataType(hdrSptr, static_cast<CM_HDR_Metadata_Type>(metadata.hdrMetadataType));
4361     }
4362     return true;
4363 #endif
4364 }
4365 
RemoveImageProperties(std::shared_ptr<MetadataAccessor> metadataAccessor,const std::set<std::string> & keys)4366 uint32_t ImageSource::RemoveImageProperties(std::shared_ptr<MetadataAccessor> metadataAccessor,
4367                                             const std::set<std::string> &keys)
4368 {
4369     bool cond = (metadataAccessor == nullptr);
4370     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_SOURCE_DATA,
4371                                "Failed to create image accessor when attempting to modify image property.");
4372     uint32_t ret = CreatExifMetadataByImageSource();
4373     cond = ret != SUCCESS;
4374     CHECK_ERROR_RETURN_RET_LOG(cond, ret, "Failed to create ExifMetadata.");
4375 
4376     bool deletFlag = false;
4377     for (auto key: keys) {
4378         bool result = exifMetadata_->RemoveEntry(key);
4379         deletFlag |= result;
4380     }
4381 
4382     cond = !deletFlag;
4383     ret = ERR_MEDIA_NO_EXIF_DATA;
4384     CHECK_ERROR_RETURN_RET(cond, ret);
4385 
4386     metadataAccessor->Set(exifMetadata_);
4387     return metadataAccessor->Write();
4388 }
4389 
4390 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
CopyRGBAToSurfaceBuffer(const DecodeContext & context,sptr<SurfaceBuffer> & sb,PlImageInfo plInfo)4391 static bool CopyRGBAToSurfaceBuffer(const DecodeContext& context, sptr<SurfaceBuffer>& sb, PlImageInfo plInfo)
4392 {
4393     bool cond = (context.info.pixelFormat != PixelFormat::RGBA_8888 &&
4394         context.info.pixelFormat != PixelFormat::BGRA_8888);
4395     CHECK_ERROR_RETURN_RET(cond, false);
4396     uint8_t* srcRow = static_cast<uint8_t*>(context.pixelsBuffer.buffer);
4397     uint8_t* dstRow = static_cast<uint8_t*>(sb->GetVirAddr());
4398     cond = srcRow == nullptr || dstRow == nullptr;
4399     CHECK_ERROR_RETURN_RET(cond, false);
4400     cond = sb->GetStride() < 0;
4401     CHECK_ERROR_RETURN_RET(cond, false);
4402     uint64_t dstStride = sb->GetStride();
4403     uint64_t srcStride = static_cast<uint64_t>(plInfo.size.width * NUM_4);
4404     uint32_t dstHeight = static_cast<uint32_t>(plInfo.size.height);
4405     for (uint32_t i = 0; i < dstHeight; i++) {
4406         errno_t err = memcpy_s(dstRow, dstStride, srcRow, srcStride);
4407         cond = err != EOK;
4408         CHECK_ERROR_RETURN_RET_LOG(cond, false, "copy data failed");
4409         srcRow += srcStride;
4410         dstRow += dstStride;
4411     }
4412     return true;
4413 }
4414 
CopyYUVToSurfaceBuffer(const DecodeContext & context,sptr<SurfaceBuffer> & buffer,PlImageInfo plInfo)4415 static bool CopyYUVToSurfaceBuffer(const DecodeContext& context, sptr<SurfaceBuffer>& buffer, PlImageInfo plInfo)
4416 {
4417     if (context.info.pixelFormat != PixelFormat::NV12 &&
4418         context.info.pixelFormat != PixelFormat::NV21) {
4419         return false;
4420     }
4421     uint8_t* srcRow = static_cast<uint8_t*>(context.pixelsBuffer.buffer);
4422     uint8_t* dstRow = static_cast<uint8_t*>(buffer->GetVirAddr());
4423     size_t dstSize = buffer->GetSize();
4424     bool cond = (buffer->GetStride() < 0);
4425     CHECK_ERROR_RETURN_RET(cond, false);
4426     YUVDataInfo yuvDataInfo = context.yuvInfo;
4427     IMAGE_LOGD("[ImageSource] CopyYUVToSurfaceBuffer yHeight = %{public}d, uvHeight = %{public}d,"
4428         "yStride = %{public}d, uvStride = %{public}d, dstSize = %{public}zu, dstStride = %{public}d",
4429         yuvDataInfo.yHeight, yuvDataInfo.uvHeight, yuvDataInfo.yStride, yuvDataInfo.uvStride,
4430         dstSize, buffer->GetStride());
4431     for (uint32_t i = 0; i < yuvDataInfo.yHeight; ++i) {
4432         if (memcpy_s(dstRow, dstSize, srcRow, yuvDataInfo.yStride) != EOK) {
4433             return false;
4434         }
4435         dstRow += buffer->GetStride();
4436         dstSize -= buffer->GetStride();
4437         srcRow += yuvDataInfo.yStride;
4438     }
4439     for (uint32_t i = 0; i < yuvDataInfo.uvHeight; ++i) {
4440         if (memcpy_s(dstRow, dstSize, srcRow, yuvDataInfo.uvStride) != EOK) {
4441             return false;
4442         }
4443         dstRow += buffer->GetStride();
4444         dstSize -= buffer->GetStride();
4445         srcRow += yuvDataInfo.uvStride;
4446     }
4447     return true;
4448 }
4449 
CopyContextIntoSurfaceBuffer(Size dstSize,const DecodeContext & context,DecodeContext & dstCtx,ImagePlugin::PlImageInfo & plInfo)4450 static uint32_t CopyContextIntoSurfaceBuffer(Size dstSize, const DecodeContext &context, DecodeContext &dstCtx,
4451     ImagePlugin::PlImageInfo& plInfo)
4452 {
4453 #if defined(_WIN32) || defined(_APPLE) || defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
4454     IMAGE_LOGE("UnSupport dma mem alloc");
4455     return ERR_IMAGE_DATA_UNSUPPORT;
4456 #else
4457     sptr<SurfaceBuffer> sb = SurfaceBuffer::Create();
4458     IMAGE_LOGD("[ImageSource]CopyContextIntoSurfaceBuffer requestConfig, sizeInfo.width:%{public}u,height:%{public}u.",
4459         context.info.size.width, context.info.size.height);
4460     GraphicPixelFormat format = GRAPHIC_PIXEL_FMT_RGBA_8888;
4461     if (context.info.pixelFormat == PixelFormat::NV21) {
4462         format = GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCRCB_420_SP;
4463     } else if (context.info.pixelFormat == PixelFormat::NV12) {
4464         format = GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCBCR_420_SP;
4465     } else if (context.info.pixelFormat == PixelFormat::BGRA_8888) {
4466         format = GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BGRA_8888;
4467     } else if (context.info.pixelFormat != PixelFormat::RGBA_8888) {
4468         IMAGE_LOGI("CopyContextIntoSurfaceBuffer pixelformat %{public}d is unsupport", context.pixelFormat);
4469         return ERR_IMAGE_DATA_UNSUPPORT;
4470     }
4471     BufferRequestConfig requestConfig = {
4472         .width = context.info.size.width,
4473         .height = context.info.size.height,
4474         .strideAlignment = 0x8, // set 0x8 as default value to alloc SurfaceBufferImpl
4475         .format = format, // PixelFormat
4476         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
4477         .timeout = 0,
4478         .colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB,
4479         .transform = GraphicTransformType::GRAPHIC_ROTATE_NONE,
4480     };
4481     GSError ret = sb->Alloc(requestConfig);
4482     if (ret != GSERROR_OK) {
4483         IMAGE_LOGE("SurfaceBuffer Alloc failed, %{public}s", GSErrorStr(ret).c_str());
4484         return ERR_DMA_NOT_EXIST;
4485     }
4486     void* nativeBuffer = sb.GetRefPtr();
4487     int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer);
4488     if (err != OHOS::GSERROR_OK) {
4489         IMAGE_LOGE("NativeBufferReference failed");
4490         return ERR_DMA_DATA_ABNORMAL;
4491     }
4492     if ((!CopyRGBAToSurfaceBuffer(context, sb, plInfo)) && (!CopyYUVToSurfaceBuffer(context, sb, plInfo))) {
4493         return ERR_IMAGE_DATA_UNSUPPORT;
4494     }
4495     SetContext(dstCtx, sb, nativeBuffer, format);
4496     return SUCCESS;
4497 #endif
4498 }
4499 
DoAiHdrProcess(sptr<SurfaceBuffer> & input,DecodeContext & hdrCtx,CM_ColorSpaceType cmColorSpaceType)4500 static uint32_t DoAiHdrProcess(sptr<SurfaceBuffer> &input, DecodeContext &hdrCtx,
4501                                CM_ColorSpaceType cmColorSpaceType)
4502 {
4503     VpeUtils::SetSbMetadataType(input, CM_METADATA_NONE);
4504     VpeUtils::SetSurfaceBufferInfo(input, cmColorSpaceType);
4505     hdrCtx.info.size.width = input->GetWidth();
4506     hdrCtx.info.size.height = input->GetHeight();
4507     auto hdrPixelFormat = GRAPHIC_PIXEL_FMT_RGBA_1010102;
4508     if (hdrCtx.photoDesiredPixelFormat == PixelFormat::YCBCR_P010) {
4509         hdrPixelFormat = GRAPHIC_PIXEL_FMT_YCBCR_P010;
4510     }
4511     uint32_t res = AllocSurfaceBuffer(hdrCtx, hdrPixelFormat);
4512     bool cond = (res != SUCCESS);
4513     CHECK_ERROR_RETURN_RET_LOG(cond, res, "HDR SurfaceBuffer Alloc failed, %{public}d", res);
4514 
4515     sptr<SurfaceBuffer> output = reinterpret_cast<SurfaceBuffer*>(hdrCtx.pixelsBuffer.context);
4516     VpeUtils::SetSbMetadataType(output, CM_IMAGE_HDR_VIVID_SINGLE);
4517     VpeUtils::SetSbColorSpaceDefault(output);
4518 
4519     std::unique_ptr<VpeUtils> utils = std::make_unique<VpeUtils>();
4520     res = utils->ColorSpaceConverterImageProcess(input, output);
4521     if (res != VPE_ERROR_OK) {
4522         IMAGE_LOGE("[ImageSource]DoAiHdrProcess ColorSpaceConverterImageProcess failed! %{public}d", res);
4523         FreeContextBuffer(hdrCtx.freeFunc, hdrCtx.allocatorType, hdrCtx.pixelsBuffer);
4524     } else {
4525         IMAGE_LOGD("[ImageSource]DoAiHdrProcess ColorSpaceConverterImageProcess Succ!");
4526         hdrCtx.hdrType = ImageHdrType::HDR_VIVID_SINGLE;
4527         hdrCtx.outInfo.size.width = output->GetWidth();
4528         hdrCtx.outInfo.size.height = output->GetHeight();
4529         if (hdrCtx.photoDesiredPixelFormat == PixelFormat::YCBCR_P010) {
4530             hdrCtx.pixelFormat = PixelFormat::YCBCR_P010;
4531             hdrCtx.info.pixelFormat = PixelFormat::YCBCR_P010;
4532         } else {
4533             hdrCtx.pixelFormat = PixelFormat::RGBA_1010102;
4534             hdrCtx.info.pixelFormat = PixelFormat::RGBA_1010102;
4535         }
4536         hdrCtx.allocatorType = AllocatorType::DMA_ALLOC;
4537     }
4538     return res;
4539 }
4540 
AiSrProcess(sptr<SurfaceBuffer> & input,DecodeContext & aisrCtx)4541 static uint32_t AiSrProcess(sptr<SurfaceBuffer> &input, DecodeContext &aisrCtx)
4542 {
4543     uint32_t res = AllocSurfaceBuffer(aisrCtx, input->GetFormat());
4544     if (res != SUCCESS) {
4545         IMAGE_LOGE("HDR SurfaceBuffer Alloc failed, %{public}d", res);
4546         return res;
4547     }
4548     sptr<SurfaceBuffer> output = reinterpret_cast<SurfaceBuffer*>(aisrCtx.pixelsBuffer.context);
4549     std::unique_ptr<VpeUtils> utils = std::make_unique<VpeUtils>();
4550     res = utils->DetailEnhancerImageProcess(input, output, static_cast<int32_t>(aisrCtx.resolutionQuality));
4551     if (res != VPE_ERROR_OK) {
4552         IMAGE_LOGE("[ImageSource]AiSrProcess DetailEnhancerImage Processed failed");
4553         FreeContextBuffer(aisrCtx.freeFunc, aisrCtx.allocatorType, aisrCtx.pixelsBuffer);
4554     } else {
4555         aisrCtx.outInfo.size.width = output->GetSurfaceBufferWidth();
4556         aisrCtx.outInfo.size.height = output->GetSurfaceBufferHeight();
4557         aisrCtx.yuvInfo.imageSize.width = aisrCtx.outInfo.size.width;
4558         aisrCtx.yuvInfo.imageSize.height = aisrCtx.outInfo.size.height;
4559         aisrCtx.hdrType = Media::ImageHdrType::SDR;
4560         IMAGE_LOGD("[ImageSource]AiSrProcess DetailEnhancerImage %{public}d %{public}d %{public}d",
4561             aisrCtx.outInfo.size.width, aisrCtx.outInfo.size.height, aisrCtx.pixelsBuffer.bufferSize);
4562     }
4563     return res;
4564 }
4565 
CheckCapacityAi()4566 static bool CheckCapacityAi()
4567 {
4568 #ifdef IMAGE_AI_ENABLE
4569     return true;
4570 #else
4571     return false;
4572 #endif
4573 }
4574 
IsNecessaryAiProcess(const Size & imageSize,const DecodeOptions & opts,bool isHdrImage,bool & needAisr,bool & needHdr)4575 static bool IsNecessaryAiProcess(const Size &imageSize, const DecodeOptions &opts, bool isHdrImage,
4576                                  bool &needAisr, bool &needHdr)
4577 {
4578     auto bRet = CheckCapacityAi();
4579     CHECK_DEBUG_RETURN_RET_LOG(!bRet, false, "[ImageSource] IsNecessaryAiProcess Unsupported sr and hdr");
4580     if (IsSizeVailed(opts.desiredSize) && (((imageSize.height != opts.desiredSize.height
4581         || imageSize.width != opts.desiredSize.width) && opts.resolutionQuality != ResolutionQuality::UNKNOWN)
4582         || opts.resolutionQuality == ResolutionQuality::HIGH)) {
4583         IMAGE_LOGD("[ImageSource] IsNecessaryAiProcess needAisr");
4584         needAisr = true;
4585     }
4586 
4587     if (opts.desiredDynamicRange == DecodeDynamicRange::HDR) {
4588         IMAGE_LOGD("[ImageSource] IsNecessaryAiProcess desiredDynamicRange is hdr");
4589         if (!isHdrImage) {
4590             IMAGE_LOGE("[ImageSource] IsNecessaryAiProcess needHdr = true;");
4591             needHdr = true;
4592         }
4593     }
4594     if (!needAisr && !needHdr) {
4595         IMAGE_LOGD("[ImageSource] no need aisr and hdr Process");
4596         return false;
4597     }
4598     IMAGE_LOGD("[ImageSource] need aisr or hdr Process :aisr %{public}d hdr:%{public}d", needAisr, needHdr);
4599     return true;
4600 }
4601 
CopySrcInfoOfContext(const DecodeContext & srcCtx,DecodeContext & dstCtx)4602 static void CopySrcInfoOfContext(const DecodeContext &srcCtx, DecodeContext &dstCtx)
4603 {
4604     dstCtx.info.size.width = srcCtx.info.size.width;
4605     dstCtx.info.size.height = srcCtx.info.size.height;
4606     dstCtx.resolutionQuality = srcCtx.resolutionQuality;
4607     dstCtx.hdrType = srcCtx.hdrType;
4608     dstCtx.pixelFormat = srcCtx.pixelFormat;
4609     dstCtx.info.pixelFormat = srcCtx.info.pixelFormat;
4610     dstCtx.info.alphaType = srcCtx.info.alphaType;
4611     dstCtx.isAisr = srcCtx.isAisr;
4612     dstCtx.grColorSpaceName = srcCtx.grColorSpaceName;
4613 }
4614 
CopyOutInfoOfContext(const DecodeContext & srcCtx,DecodeContext & dstCtx)4615 static void CopyOutInfoOfContext(const DecodeContext &srcCtx, DecodeContext &dstCtx)
4616 {
4617     dstCtx.pixelsBuffer.buffer = srcCtx.pixelsBuffer.buffer ;
4618     dstCtx.pixelsBuffer.bufferSize = srcCtx.pixelsBuffer.bufferSize;
4619     dstCtx.pixelsBuffer.context = srcCtx.pixelsBuffer.context;
4620     dstCtx.allocatorType = srcCtx.allocatorType;
4621     dstCtx.freeFunc = srcCtx.freeFunc;
4622     dstCtx.outInfo.size.width = srcCtx.outInfo.size.width;
4623     dstCtx.outInfo.size.height = srcCtx.outInfo.size.height;
4624     dstCtx.hdrType = srcCtx.hdrType;
4625     dstCtx.pixelFormat = srcCtx.pixelFormat;
4626     dstCtx.info.pixelFormat = srcCtx.info.pixelFormat;
4627     dstCtx.info.alphaType = srcCtx.info.alphaType;
4628     dstCtx.isAisr = srcCtx.isAisr;
4629     dstCtx.grColorSpaceName = srcCtx.grColorSpaceName;
4630     dstCtx.yuvInfo.imageSize.width = srcCtx.outInfo.size.width;
4631     dstCtx.yuvInfo.imageSize.height = srcCtx.outInfo.size.height;
4632     dstCtx.photoDesiredPixelFormat = srcCtx.photoDesiredPixelFormat;
4633 }
4634 
AiHdrProcess(const DecodeContext & aisrCtx,DecodeContext & hdrCtx,CM_ColorSpaceType cmColorSpaceType)4635 static uint32_t AiHdrProcess(const DecodeContext &aisrCtx, DecodeContext &hdrCtx, CM_ColorSpaceType cmColorSpaceType)
4636 {
4637     hdrCtx.pixelsBuffer.bufferSize = aisrCtx.pixelsBuffer.bufferSize;
4638     hdrCtx.info.size.width = aisrCtx.outInfo.size.width;
4639     hdrCtx.info.size.height = aisrCtx.outInfo.size.height;
4640     hdrCtx.photoDesiredPixelFormat = aisrCtx.photoDesiredPixelFormat;
4641 
4642     sptr<SurfaceBuffer> inputHdr = reinterpret_cast<SurfaceBuffer*> (aisrCtx.pixelsBuffer.context);
4643     return DoAiHdrProcess(inputHdr, hdrCtx, cmColorSpaceType);
4644 }
4645 
DoImageAiProcess(sptr<SurfaceBuffer> & input,DecodeContext & dstCtx,CM_ColorSpaceType cmColorSpaceType,bool needAisr,bool needHdr)4646 static uint32_t DoImageAiProcess(sptr<SurfaceBuffer> &input, DecodeContext &dstCtx,
4647                                  CM_ColorSpaceType cmColorSpaceType, bool needAisr, bool needHdr)
4648 {
4649     DecodeContext aiCtx;
4650     CopySrcInfoOfContext(dstCtx, aiCtx);
4651     uint32_t res = ERR_IMAGE_AI_UNSUPPORTED;
4652     if (needAisr) {
4653         res = AiSrProcess(input, aiCtx);
4654         if (res != SUCCESS) {
4655             IMAGE_LOGE("[ImageSource] AiSrProcess fail %{public}u", res);
4656         } else {
4657             CopyOutInfoOfContext(aiCtx, dstCtx);
4658             dstCtx.isAisr = true;
4659         }
4660     }
4661     if (needHdr && (dstCtx.info.pixelFormat == PixelFormat::NV12 ||
4662         dstCtx.info.pixelFormat == PixelFormat::NV21 ||
4663         dstCtx.info.pixelFormat == PixelFormat::RGBA_8888)) {
4664         sptr<SurfaceBuffer> inputHdr = input;
4665         DecodeContext hdrCtx;
4666         if (dstCtx.isAisr) {
4667             res = AiHdrProcess(aiCtx, hdrCtx, cmColorSpaceType);
4668             if (res != SUCCESS) {
4669                 res = ERR_IMAGE_AI_ONLY_SR_SUCCESS;
4670                 IMAGE_LOGE("[ImageSource] DoAiHdrProcess fail %{public}u", res);
4671                 FreeContextBuffer(hdrCtx.freeFunc, hdrCtx.allocatorType, hdrCtx.pixelsBuffer);
4672             } else {
4673                 FreeContextBuffer(aiCtx.freeFunc, aiCtx.allocatorType, aiCtx.pixelsBuffer);
4674                 CopyOutInfoOfContext(hdrCtx, dstCtx);
4675             }
4676         } else {
4677             CopySrcInfoOfContext(dstCtx, hdrCtx);
4678             res = DoAiHdrProcess(inputHdr, hdrCtx, cmColorSpaceType);
4679             if (res != SUCCESS) {
4680                 IMAGE_LOGE("[ImageSource] DoAiHdrProcess fail %{public}u", res);
4681                 FreeContextBuffer(hdrCtx.freeFunc, hdrCtx.allocatorType, hdrCtx.pixelsBuffer);
4682             } else {
4683                 CopyOutInfoOfContext(hdrCtx, dstCtx);
4684             }
4685         }
4686     }
4687     return res;
4688 }
4689 #endif
4690 
ImageAiProcess(Size imageSize,const DecodeOptions & opts,bool isHdr,DecodeContext & context,ImagePlugin::PlImageInfo & plInfo)4691 uint32_t ImageSource::ImageAiProcess(Size imageSize, const DecodeOptions &opts, bool isHdr, DecodeContext &context,
4692     ImagePlugin::PlImageInfo &plInfo)
4693 {
4694 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
4695     return ERR_MEDIA_INVALID_OPERATION;
4696 #else
4697     bool needAisr = false;
4698     bool needHdr = false;
4699     auto bRet = IsNecessaryAiProcess(imageSize, opts, isHdr, needAisr, needHdr);
4700     if (!bRet) {
4701         return ERR_IMAGE_AI_UNNECESSARY;
4702     }
4703     context.resolutionQuality = opts.resolutionQuality;
4704     DecodeContext srcCtx;
4705     CopySrcInfoOfContext(context, srcCtx);
4706     sptr<SurfaceBuffer> input = nullptr;
4707     IMAGE_LOGD("[ImageSource] ImageAiProcess allocatorType %{public}u", context.allocatorType);
4708     if (context.allocatorType == AllocatorType::DMA_ALLOC) {
4709         input = reinterpret_cast<SurfaceBuffer*> (context.pixelsBuffer.context);
4710     } else {
4711         auto res = CopyContextIntoSurfaceBuffer(imageSize, context, srcCtx, plInfo);
4712         bool cond = res != SUCCESS;
4713         CHECK_ERROR_RETURN_RET_LOG(cond, res,
4714                                    "[ImageSource] ImageAiProcess HDR SurfaceBuffer Alloc failed, %{public}d", res);
4715         input = reinterpret_cast<SurfaceBuffer*>(srcCtx.pixelsBuffer.context);
4716     }
4717     DecodeContext dstCtx;
4718     CopySrcInfoOfContext(context, dstCtx);
4719 
4720     if (IsSizeVailed(opts.desiredSize)) {
4721         dstCtx.info.size.width = opts.desiredSize.width;
4722         dstCtx.info.size.height = opts.desiredSize.height;
4723     }
4724     CM_ColorSpaceType cmColorSpaceType =
4725         ConvertColorSpaceType(mainDecoder_->GetPixelMapColorSpace().GetColorSpaceName(), true);
4726     auto res = DoImageAiProcess(input, dstCtx, cmColorSpaceType, needAisr, needHdr);
4727     if (res == SUCCESS || res == ERR_IMAGE_AI_ONLY_SR_SUCCESS) {
4728         FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer);
4729         CopyOutInfoOfContext(dstCtx, context);
4730         SetDmaContextYuvInfo(context);
4731     }
4732     FreeContextBuffer(srcCtx.freeFunc, srcCtx.allocatorType, srcCtx.pixelsBuffer);
4733     return res;
4734 #endif
4735 }
4736 
DecodeImageDataToContextExtended(uint32_t index,ImageInfo & info,ImagePlugin::PlImageInfo & plInfo,ImageEvent & imageEvent,uint32_t & errorCode)4737 DecodeContext ImageSource::DecodeImageDataToContextExtended(uint32_t index, ImageInfo &info,
4738     ImagePlugin::PlImageInfo &plInfo, ImageEvent &imageEvent, uint32_t &errorCode)
4739 {
4740     std::unique_lock<std::mutex> guard(decodingMutex_);
4741     hasDesiredSizeOptions = IsSizeVailed(opts_.desiredSize);
4742     TransformSizeWithDensity(info.size, sourceInfo_.baseDensity, opts_.desiredSize, opts_.fitDensity,
4743         opts_.desiredSize);
4744     DecodeOptions tmpOpts = opts_;
4745     if (opts_.resolutionQuality == ResolutionQuality::HIGH) {
4746         tmpOpts.desiredSize = info.size;
4747     }
4748     errorCode = SetDecodeOptions(mainDecoder_, index, tmpOpts, plInfo);
4749     if (errorCode != SUCCESS) {
4750         imageEvent.SetDecodeErrorMsg("set decode options error.ret:" + std::to_string(errorCode));
4751         IMAGE_LOGE("[ImageSource]set decode options error (index:%{public}u), ret:%{public}u.", index, errorCode);
4752         return {};
4753     }
4754     NotifyDecodeEvent(decodeListeners_, DecodeEvent::EVENT_HEADER_DECODE, &guard);
4755     auto context = DecodeImageDataToContext(index, info, plInfo, errorCode);
4756     if (context.ifPartialOutput) {
4757         NotifyDecodeEvent(decodeListeners_, DecodeEvent::EVENT_PARTIAL_DECODE, &guard);
4758     }
4759     UpdateDecodeInfoOptions(context, imageEvent);
4760     guard.unlock();
4761     return context;
4762 }
4763 
4764 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
CreatePicture(const DecodingOptionsForPicture & opts,uint32_t & errorCode)4765 std::unique_ptr<Picture> ImageSource::CreatePicture(const DecodingOptionsForPicture &opts, uint32_t &errorCode)
4766 {
4767     ImageInfo info;
4768     GetImageInfo(info);
4769     if (info.encodedFormat != IMAGE_HEIF_FORMAT && info.encodedFormat != IMAGE_JPEG_FORMAT &&
4770         info.encodedFormat != IMAGE_HEIC_FORMAT) {
4771         IMAGE_LOGE("CreatePicture failed, unsupport format: %{public}s", info.encodedFormat.c_str());
4772         errorCode = ERR_IMAGE_MISMATCHED_FORMAT;
4773         return nullptr;
4774     }
4775     DecodeOptions dopts;
4776     dopts.desiredPixelFormat = opts.desiredPixelFormat;
4777     dopts.allocatorType = opts.allocatorType;
4778     dopts.desiredDynamicRange = (ParseHdrType() && IsSingleHdrImage(sourceHdrType_)) ?
4779         DecodeDynamicRange::HDR : DecodeDynamicRange::SDR;
4780     dopts.editable = true;
4781     IMAGE_LOGI("Decode mainPixelMap: PixelFormat: %{public}d, allocatorType: %{public}d, DynamicRange: %{public}d",
4782         opts.desiredPixelFormat, dopts.allocatorType, dopts.desiredDynamicRange);
4783     std::shared_ptr<PixelMap> mainPixelMap = CreatePixelMap(dopts, errorCode);
4784     std::unique_ptr<Picture> picture = Picture::Create(mainPixelMap);
4785     if (picture == nullptr) {
4786         IMAGE_LOGE("Picture is nullptr");
4787         errorCode = ERR_IMAGE_PICTURE_CREATE_FAILED;
4788         return nullptr;
4789     }
4790 
4791     std::set<AuxiliaryPictureType> auxTypes = (opts.desireAuxiliaryPictures.size() > 0) ?
4792             opts.desireAuxiliaryPictures : ImageUtils::GetAllAuxiliaryPictureType();
4793     if (info.encodedFormat == IMAGE_HEIF_FORMAT || info.encodedFormat == IMAGE_HEIC_FORMAT) {
4794         DecodeHeifAuxiliaryPictures(auxTypes, picture, errorCode);
4795     } else if (info.encodedFormat == IMAGE_JPEG_FORMAT) {
4796         DecodeJpegAuxiliaryPicture(auxTypes, picture, errorCode);
4797     }
4798     SetHdrMetadataForPicture(picture);
4799     if (errorCode != SUCCESS) {
4800         IMAGE_LOGE("Decode auxiliary pictures failed, error code: %{public}u", errorCode);
4801     }
4802     Picture::DumpPictureIfDumpEnabled(*picture, "picture_decode_after");
4803     return picture;
4804 }
4805 
SetHdrMetadataForPicture(std::unique_ptr<Picture> & picture)4806 void ImageSource::SetHdrMetadataForPicture(std::unique_ptr<Picture> &picture)
4807 {
4808     if (picture == nullptr) {
4809         IMAGE_LOGE("%{public}s picture is nullptr", __func__);
4810         return;
4811     }
4812     std::shared_ptr<PixelMap> mainPixelMap = picture->GetMainPixel();
4813     std::shared_ptr<PixelMap> gainmapPixelMap = picture->GetGainmapPixelMap();
4814     if (mainPixelMap == nullptr || gainmapPixelMap == nullptr || gainmapPixelMap->GetHdrMetadata() == nullptr) {
4815         IMAGE_LOGW("%{public}s mainPixelMap or gainmapPixelMap or hdrMetadata is nullptr", __func__);
4816         return;
4817     }
4818     if (mainPixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC || mainPixelMap->GetFd() == nullptr ||
4819         gainmapPixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC || gainmapPixelMap->GetFd() == nullptr) {
4820         IMAGE_LOGW("%{public}s mainPixelMap or gainmapPixelMap is not DMA buffer", __func__);
4821         return;
4822     }
4823     ImageHdrType hdrType = gainmapPixelMap->GetHdrType();
4824     HdrMetadata metadata = *(gainmapPixelMap->GetHdrMetadata());
4825 
4826     CM_ColorSpaceType baseCmColor =
4827         ConvertColorSpaceType(mainPixelMap->InnerGetGrColorSpace().GetColorSpaceName(), true);
4828     // Set hdrMetadata for main
4829     sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(mainPixelMap->GetFd()));
4830     VpeUtils::SetSurfaceBufferInfo(baseSptr, false, hdrType, baseCmColor, metadata);
4831 
4832     // Set hdrMetadata for gainmap
4833     sptr<SurfaceBuffer> gainmapSptr(reinterpret_cast<SurfaceBuffer*>(gainmapPixelMap->GetFd()));
4834     CM_ColorSpaceType hdrCmColor = CM_BT2020_HLG_FULL;
4835     CM_ColorSpaceType gainmapCmColor =
4836         metadata.extendMeta.metaISO.useBaseColorFlag == ISO_USE_BASE_COLOR ? baseCmColor : hdrCmColor;
4837     SetVividMetaColor(metadata, baseCmColor, gainmapCmColor, hdrCmColor);
4838     VpeUtils::SetSurfaceBufferInfo(gainmapSptr, true, hdrType, gainmapCmColor, metadata);
4839 }
4840 
DecodeHeifAuxiliaryPictures(const std::set<AuxiliaryPictureType> & auxTypes,std::unique_ptr<Picture> & picture,uint32_t & errorCode)4841 void ImageSource::DecodeHeifAuxiliaryPictures(
4842     const std::set<AuxiliaryPictureType> &auxTypes, std::unique_ptr<Picture> &picture, uint32_t &errorCode)
4843 {
4844     if (mainDecoder_ == nullptr) {
4845         IMAGE_LOGE("mainDecoder_ is nullptr");
4846         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
4847         return;
4848     }
4849     if (picture == nullptr || picture->GetMainPixel() == nullptr) {
4850         IMAGE_LOGE("%{public}s: picture or mainPixelMap is nullptr", __func__);
4851         errorCode = ERR_IMAGE_DATA_ABNORMAL;
4852         return;
4853     }
4854     MainPictureInfo mainInfo;
4855     mainInfo.hdrType = sourceHdrType_;
4856     picture->GetMainPixel()->GetImageInfo(mainInfo.imageInfo);
4857     for (auto& auxType : auxTypes) {
4858         if (!mainDecoder_->CheckAuxiliaryMap(auxType)) {
4859             IMAGE_LOGE("The auxiliary picture type does not exist! Type: %{public}d", auxType);
4860             continue;
4861         }
4862         auto auxiliaryPicture = AuxiliaryGenerator::GenerateHeifAuxiliaryPicture(
4863             mainInfo, auxType, mainDecoder_, errorCode);
4864         if (auxiliaryPicture == nullptr) {
4865             IMAGE_LOGE("Generate heif auxiliary picture failed! Type: %{public}d, errorCode: %{public}d",
4866                 auxType, errorCode);
4867         } else {
4868             auxiliaryPicture->GetContentPixel()->SetEditable(true);
4869             picture->SetAuxiliaryPicture(auxiliaryPicture);
4870         }
4871     }
4872 }
4873 
OnlyDecodeGainmap(std::set<AuxiliaryPictureType> & auxTypes)4874 static bool OnlyDecodeGainmap(std::set<AuxiliaryPictureType> &auxTypes)
4875 {
4876     return auxTypes.size() == SINGLE_FRAME_SIZE && auxTypes.find(AuxiliaryPictureType::GAINMAP) != auxTypes.end();
4877 }
4878 
ParsingJpegAuxiliaryPictures(uint8_t * stream,uint32_t streamSize,std::set<AuxiliaryPictureType> & auxTypes,ImageHdrType hdrType)4879 static std::vector<SingleJpegImage> ParsingJpegAuxiliaryPictures(uint8_t *stream, uint32_t streamSize,
4880     std::set<AuxiliaryPictureType> &auxTypes, ImageHdrType hdrType)
4881 {
4882     ImageTrace imageTrace("%s", __func__);
4883     if (stream == nullptr || streamSize == 0) {
4884         IMAGE_LOGE("No source stream when parsing auxiliary pictures");
4885         return {};
4886     }
4887     auto jpegMpfParser = std::make_unique<JpegMpfParser>();
4888     if (!OnlyDecodeGainmap(auxTypes) && !jpegMpfParser->ParsingAuxiliaryPictures(stream, streamSize, false)) {
4889         IMAGE_LOGE("JpegMpfParser parse auxiliary pictures failed!");
4890         jpegMpfParser->images_.clear();
4891     }
4892     if (hdrType > ImageHdrType::SDR) {
4893         uint32_t gainmapStreamSize = streamSize;
4894         for (auto &image : jpegMpfParser->images_) {
4895             gainmapStreamSize = std::min(gainmapStreamSize, image.offset);
4896         }
4897         SingleJpegImage gainmapImage = {
4898             .offset = 0,
4899             .size = gainmapStreamSize,
4900             .auxType = AuxiliaryPictureType::GAINMAP,
4901             .auxTagName = AUXILIARY_TAG_GAINMAP,
4902         };
4903         jpegMpfParser->images_.push_back(gainmapImage);
4904     }
4905     return jpegMpfParser->images_;
4906 }
4907 
CheckJpegSourceStream(StreamInfo & streamInfo)4908 bool ImageSource::CheckJpegSourceStream(StreamInfo &streamInfo)
4909 {
4910     if (sourceStreamPtr_ == nullptr) {
4911         IMAGE_LOGE("%{public}s sourceStreamPtr_ is nullptr!", __func__);
4912         return false;
4913     }
4914     streamInfo.size = sourceStreamPtr_->GetStreamSize();
4915     if (streamInfo.size == 0) {
4916         IMAGE_LOGE("%{public}s source stream size from sourceStreamPtr_ is invalid!", __func__);
4917         return false;
4918     }
4919     streamInfo.buffer = sourceStreamPtr_->GetDataPtr();
4920     if (streamInfo.buffer == nullptr) {
4921         streamInfo.buffer = new (std::nothrow) uint8_t[streamInfo.size];
4922         streamInfo.needDelete = true;
4923         if (!GetStreamData(sourceStreamPtr_, streamInfo.buffer, streamInfo.size)) {
4924             IMAGE_LOGE("%{public}s GetStreamData failed!", __func__);
4925             return false;
4926         }
4927     }
4928     if (streamInfo.buffer == nullptr) {
4929         IMAGE_LOGE("%{public}s source stream is still nullptr!", __func__);
4930         return false;
4931     }
4932     if (sourceHdrType_ > ImageHdrType::SDR) {
4933         uint32_t gainmapOffset = mainDecoder_->GetGainMapOffset();
4934         if (gainmapOffset >= streamInfo.size) {
4935             IMAGE_LOGW("%{public}s skip invalid gainmapOffset: %{public}u, streamSize: %{public}u",
4936                 __func__, gainmapOffset, streamInfo.size);
4937             return true;
4938         }
4939         streamInfo.gainmapOffset = gainmapOffset;
4940     }
4941     return true;
4942 }
4943 
DecodeJpegAuxiliaryPicture(std::set<AuxiliaryPictureType> & auxTypes,std::unique_ptr<Picture> & picture,uint32_t & errorCode)4944 void ImageSource::DecodeJpegAuxiliaryPicture(
4945     std::set<AuxiliaryPictureType> &auxTypes, std::unique_ptr<Picture> &picture, uint32_t &errorCode)
4946 {
4947     StreamInfo streamInfo;
4948     if (!CheckJpegSourceStream(streamInfo) || streamInfo.buffer == nullptr || streamInfo.GetCurrentSize() == 0) {
4949         IMAGE_LOGE("Jpeg source stream is invalid!");
4950         errorCode = ERR_IMAGE_DATA_ABNORMAL;
4951         return;
4952     }
4953     auto auxInfos = ParsingJpegAuxiliaryPictures(streamInfo.GetCurrentAddress(), streamInfo.GetCurrentSize(),
4954         auxTypes, sourceHdrType_);
4955     MainPictureInfo mainInfo;
4956     mainInfo.hdrType = sourceHdrType_;
4957     picture->GetMainPixel()->GetImageInfo(mainInfo.imageInfo);
4958     for (auto &auxInfo : auxInfos) {
4959         if (auxTypes.find(auxInfo.auxType) == auxTypes.end()) {
4960             continue;
4961         }
4962         if (ImageUtils::HasOverflowed(auxInfo.offset, auxInfo.size)
4963             || auxInfo.offset + auxInfo.size > streamInfo.GetCurrentSize()) {
4964             IMAGE_LOGW("Invalid auxType: %{public}d, offset: %{public}u, size: %{public}u, streamSize: %{public}u",
4965                 auxInfo.auxType, auxInfo.offset, auxInfo.size, streamInfo.GetCurrentSize());
4966             continue;
4967         }
4968         IMAGE_LOGI("Jpeg auxiliary picture has found. Type: %{public}d", auxInfo.auxType);
4969         std::unique_ptr<InputDataStream> auxStream =
4970             BufferSourceStream::CreateSourceStream((streamInfo.GetCurrentAddress() + auxInfo.offset), auxInfo.size);
4971         if (auxStream == nullptr) {
4972             IMAGE_LOGE("Create auxiliary stream fail, auxiliary offset is %{public}u", auxInfo.offset);
4973             continue;
4974         }
4975         auto auxDecoder = std::unique_ptr<AbsImageDecoder>(
4976             DoCreateDecoder(InnerFormat::IMAGE_EXTENDED_CODEC, pluginServer_, *auxStream, errorCode));
4977         uint32_t auxErrorCode = ERROR;
4978         auto auxPicture = AuxiliaryGenerator::GenerateJpegAuxiliaryPicture(
4979             mainInfo, auxInfo.auxType, auxStream, auxDecoder, auxErrorCode);
4980         if (auxPicture != nullptr) {
4981             AuxiliaryPictureInfo auxPictureInfo = auxPicture->GetAuxiliaryPictureInfo();
4982             auxPictureInfo.jpegTagName = auxInfo.auxTagName;
4983             auxPicture->SetAuxiliaryPictureInfo(auxPictureInfo);
4984             auxPicture->GetContentPixel()->SetEditable(true);
4985             picture->SetAuxiliaryPicture(auxPicture);
4986         } else {
4987             IMAGE_LOGE("Generate jpeg auxiliary picture failed!, error: %{public}d", auxErrorCode);
4988         }
4989     }
4990 }
4991 #endif
4992 
CompressToAstcFromPixelmap(const DecodeOptions & opts,unique_ptr<PixelMap> & rgbaPixelmap,unique_ptr<AbsMemory> & dstMemory)4993 bool ImageSource::CompressToAstcFromPixelmap(const DecodeOptions &opts, unique_ptr<PixelMap> &rgbaPixelmap,
4994     unique_ptr<AbsMemory> &dstMemory)
4995 {
4996 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
4997     ImageInfo rgbaInfo;
4998     rgbaPixelmap->GetImageInfo(rgbaInfo);
4999     rgbaInfo.pixelFormat = PixelFormat::ASTC_4x4;
5000     size_t allocMemSize = ImageUtils::GetAstcBytesCount(rgbaInfo) + ASTC_TLV_SIZE;
5001 
5002     OHOS::Media::ImagePacker imagePacker;
5003     OHOS::Media::PackOption option;
5004     option.format = "image/sdr_astc_4x4";
5005     option.quality = ASTC_OPTION_QUALITY;
5006 
5007     Size desiredSize = {allocMemSize, 1};
5008     MemoryData memoryData = {nullptr, allocMemSize, "CompressToAstcFromPixelmap Data", desiredSize,
5009         opts.desiredPixelFormat};
5010     AllocatorType allocatorType = (opts.allocatorType == AllocatorType::DEFAULT) ?
5011         (IsSupportAstcZeroCopy(rgbaInfo.size) ? AllocatorType::DMA_ALLOC : AllocatorType::SHARE_MEM_ALLOC) :
5012         opts.allocatorType;
5013     dstMemory = MemoryManager::CreateMemory(allocatorType, memoryData);
5014     if (dstMemory == nullptr) {
5015         IMAGE_LOGE("CompressToAstcFromPixelmap CreateMemory failed");
5016         return false;
5017     }
5018 
5019     uint32_t ret = imagePacker.StartPacking(reinterpret_cast<uint8_t *>(dstMemory->data.data), allocMemSize, option);
5020     if (ret != 0) {
5021         IMAGE_LOGE("CompressToAstcFromPixelmap failed to start packing");
5022         return false;
5023     }
5024     ret = imagePacker.AddImage(*(rgbaPixelmap.get()));
5025     if (ret != 0) {
5026         IMAGE_LOGE("CompressToAstcFromPixelmap failed to add image");
5027         return false;
5028     }
5029     int64_t packedSize = 0;
5030     ret = imagePacker.FinalizePacking(packedSize);
5031     if (ret != 0) {
5032         IMAGE_LOGE("CompressToAstcFromPixelmap failed to finalize packing");
5033         return false;
5034     }
5035     return true;
5036 #else
5037     return false;
5038 #endif
5039 }
5040 
CreatePixelAstcFromImageFile(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)5041 unique_ptr<PixelMap> ImageSource::CreatePixelAstcFromImageFile(uint32_t index, const DecodeOptions &opts,
5042     uint32_t &errorCode)
5043 {
5044 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
5045     ImageInfo originInfo;
5046     uint32_t ret = GetImageInfo(originInfo);
5047     if (ret != SUCCESS) {
5048         IMAGE_LOGE("CreatePixelAstcFromImageFile GetImageInfo failed");
5049         return nullptr;
5050     }
5051     if ((originInfo.size.width > ASTC_MAX_SIZE || originInfo.size.height > ASTC_MAX_SIZE) ||
5052         (opts.desiredSize.width > ASTC_MAX_SIZE || opts.desiredSize.height > ASTC_MAX_SIZE)) {
5053         IMAGE_LOGE("CreatePixelAstcFromImageFile imageInfo size is too large");
5054         return nullptr;
5055     }
5056     DecodeOptions& modifiableOpts = const_cast<DecodeOptions&>(opts);
5057     modifiableOpts.desiredPixelFormat = PixelFormat::RGBA_8888;
5058     unique_ptr<PixelMap> rgbaPixelmap = CreatePixelMap(index, modifiableOpts, errorCode);
5059     if (rgbaPixelmap == nullptr) {
5060         IMAGE_LOGE("CreatePixelAstcFromImageFile pixelMap is nullptr");
5061         return nullptr;
5062     }
5063     unique_ptr<AbsMemory> dstMemory = nullptr;
5064     if (!CompressToAstcFromPixelmap(opts, rgbaPixelmap, dstMemory)) {
5065         IMAGE_LOGE("CreatePixelAstcFromImageFile CompressToAstcFromPixelmap failed");
5066         return nullptr;
5067     }
5068     unique_ptr<PixelAstc> dstPixelAstc = make_unique<PixelAstc>();
5069     ImageInfo info;
5070     if (!GetImageInfoForASTC(info, reinterpret_cast<uint8_t *>(dstMemory->data.data))) {
5071         IMAGE_LOGE("CreatePixelAstcFromImageFile get astc image info failed.");
5072         return nullptr;
5073     }
5074     ret = dstPixelAstc->SetImageInfo(info);
5075     dstPixelAstc->SetAstcRealSize(info.size);
5076     if (ret != SUCCESS) {
5077         IMAGE_LOGE("CreatePixelAstcFromImageFile update pixelmap info error ret:%{public}u.", ret);
5078         return nullptr;
5079     }
5080     dstPixelAstc->SetPixelsAddr(dstMemory->data.data, dstMemory->extend.data, dstMemory->data.size,
5081         dstMemory->GetType(), nullptr);
5082     dstPixelAstc->SetAstc(true);
5083     dstPixelAstc->SetEditable(false);
5084     ImageUtils::FlushSurfaceBuffer(dstPixelAstc.get());
5085     return dstPixelAstc;
5086 #else
5087     return nullptr;
5088 #endif
5089 }
5090 
SetSrcFd(const int & fd)5091 void ImageSource::SetSrcFd(const int& fd)
5092 {
5093     srcFd_ = dup(fd);
5094 }
5095 
SetSrcFilePath(const std::string & pathName)5096 void ImageSource::SetSrcFilePath(const std::string& pathName)
5097 {
5098     srcFilePath_ = pathName;
5099 }
5100 
SetSrcBuffer(const uint8_t * buffer,uint32_t size)5101 void ImageSource::SetSrcBuffer(const uint8_t* buffer, uint32_t size)
5102 {
5103     srcBuffer_ = const_cast<uint8_t*>(buffer);
5104     srcBufferSize_ = size;
5105 }
5106 
5107 } // namespace Media
5108 } // namespace OHOS
5109