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