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