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