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