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