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