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