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