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