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