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