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
18 #include <algorithm>
19 #include <chrono>
20 #include <cstring>
21 #include <vector>
22 #include "buffer_source_stream.h"
23 #if !defined(_WIN32) && !defined(_APPLE)
24 #include "hitrace_meter.h"
25 #include "image_trace.h"
26 #endif
27 #include "file_source_stream.h"
28 #include "image/abs_image_decoder.h"
29 #include "image/abs_image_format_agent.h"
30 #include "image/image_plugin_type.h"
31 #include "image_log.h"
32 #include "image_system_properties.h"
33 #include "image_utils.h"
34 #include "incremental_source_stream.h"
35 #include "istream_source_stream.h"
36 #include "media_errors.h"
37 #include "pixel_astc.h"
38 #include "pixel_map.h"
39 #include "plugin_server.h"
40 #include "post_proc.h"
41 #include "securec.h"
42 #include "source_stream.h"
43 #if defined(A_PLATFORM) || defined(IOS_PLATFORM)
44 #include "include/jpeg_decoder.h"
45 #else
46 #include "surface_buffer.h"
47 #endif
48 #include "include/utils/SkBase64.h"
49 #if defined(NEW_SKIA)
50 #include "include/core/SkData.h"
51 #endif
52 #include "string_ex.h"
53
54 #undef LOG_DOMAIN
55 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
56
57 #undef LOG_TAG
58 #define LOG_TAG "ImageSource"
59
60 namespace OHOS {
61 namespace Media {
62 using namespace std;
63 using namespace ImagePlugin;
64 using namespace MultimediaPlugin;
65
66 static const map<PixelFormat, PlPixelFormat> PIXEL_FORMAT_MAP = {
67 { PixelFormat::UNKNOWN, PlPixelFormat::UNKNOWN }, { PixelFormat::ARGB_8888, PlPixelFormat::ARGB_8888 },
68 { PixelFormat::ALPHA_8, PlPixelFormat::ALPHA_8 }, { PixelFormat::RGB_565, PlPixelFormat::RGB_565 },
69 { PixelFormat::RGBA_F16, PlPixelFormat::RGBA_F16 }, { PixelFormat::RGBA_8888, PlPixelFormat::RGBA_8888 },
70 { PixelFormat::BGRA_8888, PlPixelFormat::BGRA_8888 }, { PixelFormat::RGB_888, PlPixelFormat::RGB_888 },
71 { PixelFormat::NV21, PlPixelFormat::NV21 }, { PixelFormat::NV12, PlPixelFormat::NV12 },
72 { PixelFormat::CMYK, PlPixelFormat::CMYK }, { PixelFormat::ASTC_4x4, PlPixelFormat::ASTC_4X4},
73 { PixelFormat::ASTC_6x6, PlPixelFormat::ASTC_6X6}, { PixelFormat::ASTC_8x8, PlPixelFormat::ASTC_8X8}
74 };
75
76 static const map<ColorSpace, PlColorSpace> COLOR_SPACE_MAP = {
77 { ColorSpace::UNKNOWN, PlColorSpace::UNKNOWN },
78 { ColorSpace::DISPLAY_P3, PlColorSpace::DISPLAY_P3 },
79 { ColorSpace::SRGB, PlColorSpace::SRGB },
80 { ColorSpace::LINEAR_SRGB, PlColorSpace::LINEAR_SRGB },
81 { ColorSpace::EXTENDED_SRGB, PlColorSpace::EXTENDED_SRGB },
82 { ColorSpace::LINEAR_EXTENDED_SRGB, PlColorSpace::LINEAR_EXTENDED_SRGB },
83 { ColorSpace::GENERIC_XYZ, PlColorSpace::GENERIC_XYZ },
84 { ColorSpace::GENERIC_LAB, PlColorSpace::GENERIC_LAB },
85 { ColorSpace::ACES, PlColorSpace::ACES },
86 { ColorSpace::ACES_CG, PlColorSpace::ACES_CG },
87 { ColorSpace::ADOBE_RGB_1998, PlColorSpace::ADOBE_RGB_1998 },
88 { ColorSpace::DCI_P3, PlColorSpace::DCI_P3 },
89 { ColorSpace::ITU_709, PlColorSpace::ITU_709 },
90 { ColorSpace::ITU_2020, PlColorSpace::ITU_2020 },
91 { ColorSpace::ROMM_RGB, PlColorSpace::ROMM_RGB },
92 { ColorSpace::NTSC_1953, PlColorSpace::NTSC_1953 },
93 { ColorSpace::SMPTE_C, PlColorSpace::SMPTE_C }
94 };
95
96 namespace InnerFormat {
97 const string RAW_FORMAT = "image/x-raw";
98 const string ASTC_FORMAT = "image/astc";
99 const string EXTENDED_FORMAT = "image/x-skia";
100 const string IMAGE_EXTENDED_CODEC = "image/extended";
101 const string SVG_FORMAT = "image/svg+xml";
102 const string RAW_EXTENDED_FORMATS[] = {
103 "image/x-sony-arw",
104 "image/x-canon-cr2",
105 "image/x-adobe-dng",
106 "image/x-nikon-nef",
107 "image/x-nikon-nrw",
108 "image/x-olympus-orf",
109 "image/x-fuji-raf",
110 "image/x-panasonic-rw2",
111 "image/x-pentax-pef",
112 "image/x-samsung-srw",
113 };
114 } // namespace InnerFormat
115 // BASE64 image prefix type data:image/<type>;base64,<data>
116 static const std::string IMAGE_URL_PREFIX = "data:image/";
117 static const std::string BASE64_URL_PREFIX = ";base64,";
118 static const uint32_t FIRST_FRAME = 0;
119 static const int INT_ZERO = 0;
120 static const int INT_255 = 255;
121 static const size_t SIZE_ZERO = 0;
122 static const uint8_t NUM_0 = 0;
123 static const uint8_t NUM_1 = 1;
124 static const uint8_t NUM_2 = 2;
125 static const uint8_t NUM_3 = 3;
126 static const uint8_t NUM_4 = 4;
127 static const uint8_t NUM_6 = 6;
128 static const uint8_t NUM_8 = 8;
129 static const uint8_t NUM_16 = 16;
130 static const int DMA_SIZE = 512;
131 static const uint32_t ASTC_MAGIC_ID = 0x5CA1AB13;
132 static const size_t ASTC_HEADER_SIZE = 16;
133 static const uint8_t ASTC_HEADER_BLOCK_X = 4;
134 static const uint8_t ASTC_HEADER_BLOCK_Y = 5;
135 static const uint8_t ASTC_HEADER_DIM_X = 7;
136 static const uint8_t ASTC_HEADER_DIM_Y = 10;
137
138 PluginServer &ImageSource::pluginServer_ = ImageUtils::GetPluginServer();
139 ImageSource::FormatAgentMap ImageSource::formatAgentMap_ = InitClass();
140
GetSupportedFormats(set<string> & formats)141 uint32_t ImageSource::GetSupportedFormats(set<string> &formats)
142 {
143 IMAGE_LOGD("[ImageSource]get supported image type.");
144
145 formats.clear();
146 vector<ClassInfo> classInfos;
147 uint32_t ret = pluginServer_.PluginServerGetClassInfo<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT,
148 classInfos);
149 if (ret != SUCCESS) {
150 IMAGE_LOGE("[ImageSource]get class info from plugin server failed, ret:%{public}u.", ret);
151 return ret;
152 }
153
154 for (auto &info : classInfos) {
155 map<string, AttrData> &capbility = info.capabilities;
156 auto iter = capbility.find(IMAGE_ENCODE_FORMAT);
157 if (iter == capbility.end()) {
158 continue;
159 }
160
161 AttrData &attr = iter->second;
162 const string *format = nullptr;
163 if (attr.GetValue(format) != SUCCESS) {
164 IMAGE_LOGE("[ImageSource]attr data get format failed.");
165 continue;
166 }
167
168 if (*format == InnerFormat::RAW_FORMAT) {
169 formats.insert(std::begin(InnerFormat::RAW_EXTENDED_FORMATS), std::end(InnerFormat::RAW_EXTENDED_FORMATS));
170 } else {
171 formats.insert(*format);
172 }
173 }
174 return SUCCESS;
175 }
176
DoImageSourceCreate(std::function<unique_ptr<SourceStream> (void)> stream,const SourceOptions & opts,uint32_t & errorCode,const string traceName)177 unique_ptr<ImageSource> ImageSource::DoImageSourceCreate(
178 std::function<unique_ptr<SourceStream>(void)> stream,
179 const SourceOptions &opts, uint32_t &errorCode, const string traceName)
180 {
181 ImageTrace imageTrace(traceName);
182 IMAGE_LOGD("[ImageSource]DoImageSourceCreate IN.");
183 errorCode = ERR_IMAGE_SOURCE_DATA;
184 auto streamPtr = stream();
185 if (streamPtr == nullptr) {
186 return nullptr;
187 }
188
189 auto sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
190 if (sourcePtr == nullptr) {
191 IMAGE_LOGE("[ImageSource]failed to create ImageSource.");
192 return nullptr;
193 }
194 errorCode = SUCCESS;
195 return unique_ptr<ImageSource>(sourcePtr);
196 }
197
CreateImageSource(unique_ptr<istream> is,const SourceOptions & opts,uint32_t & errorCode)198 unique_ptr<ImageSource> ImageSource::CreateImageSource(unique_ptr<istream> is,
199 const SourceOptions &opts, uint32_t &errorCode)
200 {
201 IMAGE_LOGD("[ImageSource]create Imagesource with stream.");
202 return DoImageSourceCreate([&is]() {
203 auto stream = IstreamSourceStream::CreateSourceStream(move(is));
204 if (stream == nullptr) {
205 IMAGE_LOGE("[ImageSource]failed to create istream source stream.");
206 }
207 return stream;
208 }, opts, errorCode, "CreateImageSource by istream");
209 }
210
CreateImageSource(const uint8_t * data,uint32_t size,const SourceOptions & opts,uint32_t & errorCode)211 unique_ptr<ImageSource> ImageSource::CreateImageSource(const uint8_t *data, uint32_t size,
212 const SourceOptions &opts, uint32_t &errorCode)
213 {
214 IMAGE_LOGD("[ImageSource]create Imagesource with buffer.");
215
216 if (data == nullptr || size == 0) {
217 IMAGE_LOGE("[ImageSource]parameter error.");
218 errorCode = ERR_MEDIA_INVALID_PARAM;
219 return nullptr;
220 }
221 return DoImageSourceCreate([&data, &size]() {
222 auto streamPtr = DecodeBase64(data, size);
223 if (streamPtr == nullptr) {
224 streamPtr = BufferSourceStream::CreateSourceStream(data, size);
225 }
226 if (streamPtr == nullptr) {
227 IMAGE_LOGE("[ImageSource]failed to create buffer source stream.");
228 }
229 return streamPtr;
230 }, opts, errorCode, "CreateImageSource by data");
231 }
232
CreateImageSource(const std::string & pathName,const SourceOptions & opts,uint32_t & errorCode)233 unique_ptr<ImageSource> ImageSource::CreateImageSource(const std::string &pathName, const SourceOptions &opts,
234 uint32_t &errorCode)
235 {
236 IMAGE_LOGD("[ImageSource]create Imagesource with pathName.");
237 if (pathName.size() == SIZE_ZERO) {
238 IMAGE_LOGE("[ImageSource]parameter error.");
239 return nullptr;
240 }
241 return DoImageSourceCreate([&pathName]() {
242 auto streamPtr = DecodeBase64(pathName);
243 if (streamPtr == nullptr) {
244 streamPtr = FileSourceStream::CreateSourceStream(pathName);
245 }
246 if (streamPtr == nullptr) {
247 IMAGE_LOGE("[ImageSource]failed to create file path source stream. pathName=%{public}s",
248 pathName.c_str());
249 }
250 return streamPtr;
251 }, opts, errorCode, "CreateImageSource by path");
252 }
253
CreateImageSource(const int fd,const SourceOptions & opts,uint32_t & errorCode)254 unique_ptr<ImageSource> ImageSource::CreateImageSource(const int fd, const SourceOptions &opts,
255 uint32_t &errorCode)
256 {
257 IMAGE_LOGD("[ImageSource]create Imagesource with fd.");
258 return DoImageSourceCreate([&fd]() {
259 auto streamPtr = FileSourceStream::CreateSourceStream(fd);
260 if (streamPtr == nullptr) {
261 IMAGE_LOGE("[ImageSource]failed to create file fd source stream.");
262 }
263 return streamPtr;
264 }, opts, errorCode, "CreateImageSource by fd");
265 }
266
CreateImageSource(const int fd,int32_t offset,int32_t length,const SourceOptions & opts,uint32_t & errorCode)267 unique_ptr<ImageSource> ImageSource::CreateImageSource(const int fd, int32_t offset,
268 int32_t length, const SourceOptions &opts, uint32_t &errorCode)
269 {
270 IMAGE_LOGD("[ImageSource]create Imagesource with fd offset and length.");
271 return DoImageSourceCreate([&fd, offset, length]() {
272 auto streamPtr = FileSourceStream::CreateSourceStream(fd, offset, length);
273 if (streamPtr == nullptr) {
274 IMAGE_LOGE("[ImageSource]failed to create file fd source stream.");
275 }
276 return streamPtr;
277 }, opts, errorCode, "CreateImageSource by fd offset and length");
278 }
279
CreateIncrementalImageSource(const IncrementalSourceOptions & opts,uint32_t & errorCode)280 unique_ptr<ImageSource> ImageSource::CreateIncrementalImageSource(const IncrementalSourceOptions &opts,
281 uint32_t &errorCode)
282 {
283 IMAGE_LOGD("[ImageSource]create incremental ImageSource.");
284 auto sourcePtr = DoImageSourceCreate([&opts]() {
285 auto streamPtr = IncrementalSourceStream::CreateSourceStream(opts.incrementalMode);
286 if (streamPtr == nullptr) {
287 IMAGE_LOGE("[ImageSource]failed to create incremental source stream.");
288 }
289 return streamPtr;
290 }, opts.sourceOptions, errorCode, "CreateImageSource by fd");
291 if (sourcePtr != nullptr) {
292 sourcePtr->SetIncrementalSource(true);
293 }
294 return sourcePtr;
295 }
296
Reset()297 void ImageSource::Reset()
298 {
299 // if use skia now, no need reset
300 if (mainDecoder_ != nullptr && mainDecoder_->HasProperty(SKIA_DECODER)) {
301 return;
302 }
303 imageStatusMap_.clear();
304 decodeState_ = SourceDecodingState::UNRESOLVED;
305 sourceStreamPtr_->Seek(0);
306 mainDecoder_ = nullptr;
307 }
308
CreatePixelMapEx(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)309 unique_ptr<PixelMap> ImageSource::CreatePixelMapEx(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
310 {
311 ImageTrace imageTrace("ImageSource::CreatePixelMapEx, index:%u, desiredSize:(%d, %d)", index,
312 opts.desiredSize.width, opts.desiredSize.height);
313 IMAGE_LOGD(
314 "CreatePixelMapEx imageId_: %{public}lu, desiredPixelFormat: %{public}d,"
315 "desiredSize: (%{public}d, %{public}d)", static_cast<unsigned long>(imageId_), opts.desiredPixelFormat,
316 opts.desiredSize.width, opts.desiredSize.height);
317
318 #if !defined(A_PLATFORM) || !defined(IOS_PLATFORM)
319 if (!isAstc_.has_value()) {
320 ImagePlugin::DataStreamBuffer outData;
321 uint32_t res = GetData(outData, ASTC_HEADER_SIZE);
322 if (res == SUCCESS) {
323 isAstc_ = IsASTC(outData.inputStreamBuffer, outData.dataSize);
324 }
325 }
326 if (isAstc_.has_value() && isAstc_.value()) {
327 return CreatePixelMapForASTC(errorCode);
328 }
329 #endif
330
331 if (IsSpecialYUV()) {
332 return CreatePixelMapForYUV(errorCode);
333 }
334
335 DumpInputData();
336 return CreatePixelMap(index, opts, errorCode);
337 }
338
IsExtendedCodec(AbsImageDecoder * decoder)339 static bool IsExtendedCodec(AbsImageDecoder* decoder)
340 {
341 const static string ENCODED_FORMAT_KEY = "EncodedFormat";
342 if (decoder != nullptr && decoder->HasProperty(ENCODED_FORMAT_KEY)) {
343 return true;
344 }
345 return false;
346 }
347
IsSizeVailed(const Size & size)348 static inline bool IsSizeVailed(const Size &size)
349 {
350 return (size.width != INT_ZERO && size.height != INT_ZERO);
351 }
352
CopySize(const Size & src,Size & dst)353 static inline void CopySize(const Size &src, Size &dst)
354 {
355 dst.width = src.width;
356 dst.height = src.height;
357 }
358
IsDensityChange(int32_t srcDensity,int32_t wantDensity)359 static inline bool IsDensityChange(int32_t srcDensity, int32_t wantDensity)
360 {
361 return (srcDensity != 0 && wantDensity != 0 && srcDensity != wantDensity);
362 }
363
GetScalePropByDensity(int32_t prop,int32_t srcDensity,int32_t wantDensity)364 static inline int32_t GetScalePropByDensity(int32_t prop, int32_t srcDensity, int32_t wantDensity)
365 {
366 if (srcDensity != 0) {
367 return (prop * wantDensity + (srcDensity >> 1)) / srcDensity;
368 }
369 return prop;
370 }
371
TransformSizeWithDensity(const Size & srcSize,int32_t srcDensity,const Size & wantSize,int32_t wantDensity,Size & dstSize)372 static void TransformSizeWithDensity(const Size &srcSize, int32_t srcDensity, const Size &wantSize,
373 int32_t wantDensity, Size &dstSize)
374 {
375 if (IsSizeVailed(wantSize)) {
376 CopySize(wantSize, dstSize);
377 } else {
378 CopySize(srcSize, dstSize);
379 }
380 if (IsDensityChange(srcDensity, wantDensity)) {
381 dstSize.width = GetScalePropByDensity(dstSize.width, srcDensity, wantDensity);
382 dstSize.height = GetScalePropByDensity(dstSize.height, srcDensity, wantDensity);
383 }
384 }
385
NotifyDecodeEvent(set<DecodeListener * > & listeners,DecodeEvent event,std::unique_lock<std::mutex> * guard)386 static void NotifyDecodeEvent(set<DecodeListener *> &listeners, DecodeEvent event,
387 std::unique_lock<std::mutex>* guard)
388 {
389 if (listeners.size() == SIZE_ZERO) {
390 return;
391 }
392 for (auto listener : listeners) {
393 if (guard != nullptr) {
394 guard->unlock();
395 }
396 listener->OnEvent(static_cast<int>(event));
397 if (guard != nullptr) {
398 guard->lock();
399 }
400 }
401 }
402
FreeContextBuffer(const Media::CustomFreePixelMap & func,AllocatorType allocType,PlImageBuffer & buffer)403 static void FreeContextBuffer(const Media::CustomFreePixelMap &func,
404 AllocatorType allocType, PlImageBuffer &buffer)
405 {
406 if (func != nullptr) {
407 func(buffer.buffer, buffer.context, buffer.bufferSize);
408 return;
409 }
410
411 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
412 if (allocType == AllocatorType::SHARE_MEM_ALLOC) {
413 int *fd = static_cast<int *>(buffer.context);
414 if (buffer.buffer != nullptr) {
415 ::munmap(buffer.buffer, buffer.bufferSize);
416 }
417 if (fd != nullptr) {
418 ::close(*fd);
419 }
420 return;
421 } else if (allocType == AllocatorType::DMA_ALLOC) {
422 if (buffer.buffer != nullptr) {
423 ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer*>(buffer.context));
424 buffer.context = nullptr;
425 }
426 } else if (allocType == AllocatorType::HEAP_ALLOC) {
427 if (buffer.buffer != nullptr) {
428 free(buffer.buffer);
429 buffer.buffer = nullptr;
430 }
431 }
432 #else
433 if (buffer.buffer != nullptr) {
434 free(buffer.buffer);
435 buffer.buffer = nullptr;
436 }
437 #endif
438 }
439
ContextToAddrInfos(DecodeContext & context,PixelMapAddrInfos & addrInfos)440 static void ContextToAddrInfos(DecodeContext &context, PixelMapAddrInfos &addrInfos)
441 {
442 addrInfos.addr = static_cast<uint8_t*>(context.pixelsBuffer.buffer);
443 addrInfos.context =static_cast<uint8_t*>(context.pixelsBuffer.context);
444 addrInfos.size =context.pixelsBuffer.bufferSize;
445 addrInfos.type =context.allocatorType;
446 addrInfos.func =context.freeFunc;
447 }
448
IsSupportFormat(const PixelFormat & format)449 bool IsSupportFormat(const PixelFormat &format)
450 {
451 return format == PixelFormat::UNKNOWN || format == PixelFormat::RGBA_8888;
452 }
453
IsSupportSize(const Size & size)454 bool IsSupportSize(const Size &size)
455 {
456 return size.width >= DMA_SIZE && size.height >= DMA_SIZE;
457 }
458
IsWidthAligned(const int32_t & width)459 bool IsWidthAligned(const int32_t &width)
460 {
461 return ((width * NUM_4) & INT_255) == 0;
462 }
463
IsSupportDma(const DecodeOptions & opts,const ImageInfo & info,bool hasDesiredSizeOptions)464 bool IsSupportDma(const DecodeOptions &opts, const ImageInfo &info, bool hasDesiredSizeOptions)
465 {
466 #if defined(_WIN32) || defined(_APPLE) || defined(A_PLATFORM) || defined(IOS_PLATFORM)
467 IMAGE_LOGE("Unsupport dma mem alloc");
468 return false;
469 #else
470 // used for test surfacebuffer
471 if (ImageSystemProperties::GetSurfaceBufferEnabled() &&
472 IsSupportSize(hasDesiredSizeOptions ? opts.desiredSize : info.size)) {
473 return true;
474 }
475
476 if (ImageSystemProperties::GetDmaEnabled() && IsSupportFormat(opts.desiredPixelFormat)) {
477 return IsSupportSize(hasDesiredSizeOptions ? opts.desiredSize : info.size) &&
478 (IsWidthAligned(opts.desiredSize.width) || opts.preferDma);
479 }
480 return false;
481 #endif
482 }
483
InitDecodeContext(const DecodeOptions & opts,const ImageInfo & info,const MemoryUsagePreference & preference,bool hasDesiredSizeOptions)484 DecodeContext InitDecodeContext(const DecodeOptions &opts, const ImageInfo &info,
485 const MemoryUsagePreference &preference, bool hasDesiredSizeOptions)
486 {
487 DecodeContext context;
488 if (opts.allocatorType != AllocatorType::DEFAULT) {
489 context.allocatorType = opts.allocatorType;
490 } else {
491 if (preference == MemoryUsagePreference::DEFAULT && IsSupportDma(opts, info, hasDesiredSizeOptions)) {
492 IMAGE_LOGD("[ImageSource] allocatorType is DMA_ALLOC");
493 context.allocatorType = AllocatorType::DMA_ALLOC;
494 } else {
495 context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
496 }
497 }
498 return context;
499 }
500
GetNowTimeMicroSeconds()501 uint64_t ImageSource::GetNowTimeMicroSeconds()
502 {
503 auto now = std::chrono::system_clock::now();
504 return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
505 }
506
CreatePixelMapExtended(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)507 unique_ptr<PixelMap> ImageSource::CreatePixelMapExtended(uint32_t index,
508 const DecodeOptions &opts, uint32_t &errorCode)
509 {
510 uint64_t decodeStartTime = GetNowTimeMicroSeconds();
511 opts_ = opts;
512 ImageInfo info;
513 errorCode = GetImageInfo(FIRST_FRAME, info);
514 ImageTrace imageTrace("CreatePixelMapExtended, info.size:(%d, %d)", info.size.width, info.size.height);
515 if (errorCode != SUCCESS || !IsSizeVailed(info.size)) {
516 IMAGE_LOGE("[ImageSource]get image info failed, ret:%{public}u.", errorCode);
517 errorCode = ERR_IMAGE_DATA_ABNORMAL;
518 return nullptr;
519 }
520 std::unique_lock<std::mutex> guard(decodingMutex_);
521 hasDesiredSizeOptions = IsSizeVailed(opts_.desiredSize);
522 TransformSizeWithDensity(info.size, sourceInfo_.baseDensity, opts_.desiredSize, opts_.fitDensity,
523 opts_.desiredSize);
524 ImagePlugin::PlImageInfo plInfo;
525 errorCode = SetDecodeOptions(mainDecoder_, index, opts_, plInfo);
526 if (errorCode != SUCCESS) {
527 IMAGE_LOGE("[ImageSource]set decode options error (index:%{public}u), ret:%{public}u.", index, errorCode);
528 return nullptr;
529 }
530 NotifyDecodeEvent(decodeListeners_, DecodeEvent::EVENT_HEADER_DECODE, &guard);
531 DecodeContext context = InitDecodeContext(opts_, info, preference_, hasDesiredSizeOptions);
532
533 errorCode = mainDecoder_->Decode(index, context);
534 if (context.ifPartialOutput) {
535 NotifyDecodeEvent(decodeListeners_, DecodeEvent::EVENT_PARTIAL_DECODE, &guard);
536 }
537 ninePatchInfo_.ninePatch = context.ninePatchContext.ninePatch;
538 ninePatchInfo_.patchSize = context.ninePatchContext.patchSize;
539 guard.unlock();
540 if (errorCode != SUCCESS) {
541 IMAGE_LOGE("[ImageSource]decode source fail, ret:%{public}u.", errorCode);
542 FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer);
543 return nullptr;
544 }
545 PixelMapAddrInfos addrInfos;
546 ContextToAddrInfos(context, addrInfos);
547 auto pixelMap = CreatePixelMapByInfos(plInfo, addrInfos, errorCode);
548 if (pixelMap == nullptr) {
549 return nullptr;
550 }
551 if (!context.ifPartialOutput) {
552 NotifyDecodeEvent(decodeListeners_, DecodeEvent::EVENT_COMPLETE_DECODE, nullptr);
553 }
554 IMAGE_LOGI("CreatePixelMapExtended success, imageId:%{public}lu, desiredSize: (%{public}d, %{public}d),"
555 "imageSize: (%{public}d, %{public}d), cost %{public}lu us", static_cast<unsigned long>(imageId_),
556 opts.desiredSize.width, opts.desiredSize.height, info.size.width, info.size.height,
557 static_cast<unsigned long>(GetNowTimeMicroSeconds() - decodeStartTime));
558 return pixelMap;
559 }
560
GetValidCropRect(const Rect & src,ImagePlugin::PlImageInfo & plInfo,Rect & dst)561 static void GetValidCropRect(const Rect &src, ImagePlugin::PlImageInfo &plInfo, Rect &dst)
562 {
563 dst.top = src.top;
564 dst.left = src.left;
565 dst.width = src.width;
566 dst.height = src.height;
567 int32_t dstBottom = dst.top + dst.height;
568 int32_t dstRight = dst.left + dst.width;
569 if (dst.top >= 0 && dstBottom > 0 && static_cast<uint32_t>(dstBottom) > plInfo.size.height) {
570 dst.height = plInfo.size.height - dst.top;
571 }
572 if (dst.left >= 0 && dstRight > 0 && static_cast<uint32_t>(dstRight) > plInfo.size.width) {
573 dst.width = plInfo.size.width - dst.left;
574 }
575 }
576
ResizeCropPixelmap(PixelMap & pixelmap,int32_t srcDensity,int32_t wantDensity,Size & dstSize)577 static void ResizeCropPixelmap(PixelMap &pixelmap, int32_t srcDensity, int32_t wantDensity, Size &dstSize)
578 {
579 ImageInfo info;
580 pixelmap.GetImageInfo(info);
581 if (!IsDensityChange(srcDensity, wantDensity)) {
582 dstSize.width = info.size.width;
583 dstSize.height = info.size.height;
584 } else {
585 dstSize.width = GetScalePropByDensity(info.size.width, srcDensity, wantDensity);
586 dstSize.height = GetScalePropByDensity(info.size.height, srcDensity, wantDensity);
587 }
588 }
589
CreatePixelMapByInfos(ImagePlugin::PlImageInfo & plInfo,PixelMapAddrInfos & addrInfos,uint32_t & errorCode)590 unique_ptr<PixelMap> ImageSource::CreatePixelMapByInfos(ImagePlugin::PlImageInfo &plInfo,
591 PixelMapAddrInfos &addrInfos, uint32_t &errorCode)
592 {
593 unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
594 #ifdef IMAGE_COLORSPACE_FLAG
595 // add graphic colorspace object to pixelMap.
596 bool isSupportICCProfile = mainDecoder_->IsSupportICCProfile();
597 if (isSupportICCProfile) {
598 OHOS::ColorManager::ColorSpace grColorSpace = mainDecoder_->getGrColorSpace();
599 pixelMap->InnerSetColorSpace(grColorSpace);
600 }
601 #endif
602 pixelMap->SetPixelsAddr(addrInfos.addr, addrInfos.context, addrInfos.size, addrInfos.type, addrInfos.func);
603 errorCode = UpdatePixelMapInfo(opts_, plInfo, *(pixelMap.get()), opts_.fitDensity, true);
604 if (errorCode != SUCCESS) {
605 IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
606 return nullptr;
607 }
608 auto saveEditable = pixelMap->IsEditable();
609 pixelMap->SetEditable(true);
610 // Need check pixel change:
611 // 1. pixel size
612 // 2. crop
613 // 3. density
614 // 4. rotate
615 // 5. format
616 const static string SUPPORT_CROP_KEY = "SupportCrop";
617 if (!mainDecoder_->HasProperty(SUPPORT_CROP_KEY) &&
618 opts_.CropRect.width > INT_ZERO && opts_.CropRect.height > INT_ZERO) {
619 Rect crop;
620 GetValidCropRect(opts_.CropRect, plInfo, crop);
621 errorCode = pixelMap->crop(crop);
622 if (errorCode != SUCCESS) {
623 IMAGE_LOGE("[ImageSource]CropRect pixelmap fail, ret:%{public}u.", errorCode);
624 return nullptr;
625 }
626 if (!hasDesiredSizeOptions) {
627 ResizeCropPixelmap(*pixelMap, sourceInfo_.baseDensity, opts_.fitDensity, opts_.desiredSize);
628 }
629 }
630 // rotateDegrees and rotateNewDegrees
631 if (!ImageUtils::FloatCompareZero(opts_.rotateDegrees)) {
632 pixelMap->rotate(opts_.rotateDegrees);
633 } else if (opts_.rotateNewDegrees != INT_ZERO) {
634 pixelMap->rotate(opts_.rotateNewDegrees);
635 }
636 ImageUtils::DumpPixelMapIfDumpEnabled(pixelMap, imageId_);
637 if (opts_.desiredSize.height != pixelMap->GetHeight() ||
638 opts_.desiredSize.width != pixelMap->GetWidth()) {
639 float xScale = static_cast<float>(opts_.desiredSize.width)/pixelMap->GetWidth();
640 float yScale = static_cast<float>(opts_.desiredSize.height)/pixelMap->GetHeight();
641 if (!pixelMap->resize(xScale, yScale)) {
642 return nullptr;
643 }
644 // dump pixelMap after resize
645 ImageUtils::DumpPixelMapIfDumpEnabled(pixelMap, imageId_);
646 }
647 pixelMap->SetEditable(saveEditable);
648 return pixelMap;
649 }
650
CreatePixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)651 unique_ptr<PixelMap> ImageSource::CreatePixelMap(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
652 {
653 std::unique_lock<std::mutex> guard(decodingMutex_);
654 opts_ = opts;
655 bool useSkia = opts_.sampleSize != 1;
656 if (useSkia) {
657 // we need reset to initial state to choose correct decoder
658 Reset();
659 }
660 auto iter = GetValidImageStatus(index, errorCode);
661 if (iter == imageStatusMap_.end()) {
662 IMAGE_LOGE("[ImageSource]get valid image status fail on create pixel map, ret:%{public}u.", errorCode);
663 return nullptr;
664 }
665 if (ImageSystemProperties::GetSkiaEnabled()) {
666 if (IsExtendedCodec(mainDecoder_.get())) {
667 guard.unlock();
668 return CreatePixelMapExtended(index, opts, errorCode);
669 }
670 }
671
672 // the mainDecoder_ may be borrowed by Incremental decoding, so needs to be checked.
673 if (InitMainDecoder() != SUCCESS) {
674 IMAGE_LOGE("[ImageSource]image decode plugin is null.");
675 errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
676 return nullptr;
677 }
678 unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
679 if (pixelMap == nullptr || pixelMap.get() == nullptr) {
680 IMAGE_LOGE("[ImageSource]create the pixel map unique_ptr fail.");
681 errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
682 return nullptr;
683 }
684
685 ImagePlugin::PlImageInfo plInfo;
686 errorCode = SetDecodeOptions(mainDecoder_, index, opts_, plInfo);
687 if (errorCode != SUCCESS) {
688 IMAGE_LOGE("[ImageSource]set decode options error (index:%{public}u), ret:%{public}u.", index,
689 errorCode);
690 return nullptr;
691 }
692
693 for (auto listener : decodeListeners_) {
694 guard.unlock();
695 listener->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
696 guard.lock();
697 }
698
699 Size size = {
700 .width = plInfo.size.width,
701 .height = plInfo.size.height
702 };
703 PostProc::ValidCropValue(opts_.CropRect, size);
704 errorCode = UpdatePixelMapInfo(opts_, plInfo, *(pixelMap.get()));
705 if (errorCode != SUCCESS) {
706 IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
707 return nullptr;
708 }
709
710 DecodeContext context;
711 FinalOutputStep finalOutputStep = FinalOutputStep::NO_CHANGE;
712 context.pixelmapUniqueId_ = pixelMap->GetUniqueId();
713 if (!useSkia) {
714 bool hasNinePatch = mainDecoder_->HasProperty(NINE_PATCH);
715 finalOutputStep = GetFinalOutputStep(opts_, *(pixelMap.get()), hasNinePatch);
716 IMAGE_LOGD("[ImageSource]finalOutputStep:%{public}d. opts.allocatorType %{public}d",
717 finalOutputStep, opts_.allocatorType);
718
719 if (finalOutputStep == FinalOutputStep::NO_CHANGE) {
720 context.allocatorType = opts_.allocatorType;
721 } else {
722 context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
723 }
724 }
725
726 errorCode = mainDecoder_->Decode(index, context);
727 if (context.ifPartialOutput) {
728 for (auto partialListener : decodeListeners_) {
729 guard.unlock();
730 partialListener->OnEvent((int)DecodeEvent::EVENT_PARTIAL_DECODE);
731 guard.lock();
732 }
733 }
734 if (!useSkia) {
735 ninePatchInfo_.ninePatch = context.ninePatchContext.ninePatch;
736 ninePatchInfo_.patchSize = context.ninePatchContext.patchSize;
737 }
738 guard.unlock();
739 if (errorCode != SUCCESS) {
740 IMAGE_LOGE("[ImageSource]decode source fail, ret:%{public}u.", errorCode);
741 if (context.pixelsBuffer.buffer != nullptr) {
742 if (context.freeFunc != nullptr) {
743 context.freeFunc(context.pixelsBuffer.buffer, context.pixelsBuffer.context,
744 context.pixelsBuffer.bufferSize);
745 } else {
746 PixelMap::ReleaseMemory(context.allocatorType, context.pixelsBuffer.buffer,
747 context.pixelsBuffer.context, context.pixelsBuffer.bufferSize);
748 }
749 }
750 return nullptr;
751 }
752
753 #ifdef IMAGE_COLORSPACE_FLAG
754 // add graphic colorspace object to pixelMap.
755 bool isSupportICCProfile = mainDecoder_->IsSupportICCProfile();
756 if (isSupportICCProfile) {
757 OHOS::ColorManager::ColorSpace grColorSpace = mainDecoder_->getGrColorSpace();
758 pixelMap->InnerSetColorSpace(grColorSpace);
759 }
760 #endif
761
762 pixelMap->SetPixelsAddr(context.pixelsBuffer.buffer, context.pixelsBuffer.context, context.pixelsBuffer.bufferSize,
763 context.allocatorType, context.freeFunc);
764 DecodeOptions procOpts;
765 CopyOptionsToProcOpts(opts_, procOpts, *(pixelMap.get()));
766 PostProc postProc;
767 errorCode = postProc.DecodePostProc(procOpts, *(pixelMap.get()), finalOutputStep);
768 if (errorCode != SUCCESS) {
769 return nullptr;
770 }
771
772 if (!context.ifPartialOutput) {
773 for (auto listener : decodeListeners_) {
774 listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
775 }
776 }
777 // not ext decode, dump pixelMap while decoding svg here
778 ImageUtils::DumpPixelMapIfDumpEnabled(pixelMap, imageId_);
779 return pixelMap;
780 }
781
CreateIncrementalPixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)782 unique_ptr<IncrementalPixelMap> ImageSource::CreateIncrementalPixelMap(uint32_t index, const DecodeOptions &opts,
783 uint32_t &errorCode)
784 {
785 IncrementalPixelMap *incPixelMapPtr = new (std::nothrow) IncrementalPixelMap(index, opts, this);
786 if (incPixelMapPtr == nullptr) {
787 IMAGE_LOGE("[ImageSource]create the incremental pixel map unique_ptr fail.");
788 errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
789 return nullptr;
790 }
791 errorCode = SUCCESS;
792 return unique_ptr<IncrementalPixelMap>(incPixelMapPtr);
793 }
794
PromoteDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,ImageDecodingState & state,uint8_t & decodeProgress)795 uint32_t ImageSource::PromoteDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
796 ImageDecodingState &state, uint8_t &decodeProgress)
797 {
798 state = ImageDecodingState::UNRESOLVED;
799 decodeProgress = 0;
800 uint32_t ret = SUCCESS;
801 std::unique_lock<std::mutex> guard(decodingMutex_);
802 opts_ = opts;
803 auto imageStatusIter = GetValidImageStatus(index, ret);
804 if (imageStatusIter == imageStatusMap_.end()) {
805 IMAGE_LOGE("[ImageSource]get valid image status fail on promote decoding, ret:%{public}u.", ret);
806 return ret;
807 }
808 auto incrementalRecordIter = incDecodingMap_.find(&pixelMap);
809 if (incrementalRecordIter == incDecodingMap_.end()) {
810 ret = AddIncrementalContext(pixelMap, incrementalRecordIter);
811 if (ret != SUCCESS) {
812 IMAGE_LOGE("[ImageSource]failed to add context on incremental decoding, ret:%{public}u.", ret);
813 return ret;
814 }
815 }
816 if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::BASE_INFO_PARSED) {
817 IMAGE_LOGD("[ImageSource]promote decode : set decode options.");
818 ImagePlugin::PlImageInfo plInfo;
819 ret = SetDecodeOptions(incrementalRecordIter->second.decoder, index, opts_, plInfo);
820 if (ret != SUCCESS) {
821 IMAGE_LOGE("[ImageSource]set decode options error (image index:%{public}u), ret:%{public}u.",
822 index, ret);
823 return ret;
824 }
825
826 auto iterator = decodeEventMap_.find((int)DecodeEvent::EVENT_HEADER_DECODE);
827 if (iterator == decodeEventMap_.end()) {
828 decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_HEADER_DECODE, 1));
829 for (auto callback : decodeListeners_) {
830 guard.unlock();
831 callback->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
832 guard.lock();
833 }
834 }
835 Size size = {
836 .width = plInfo.size.width,
837 .height = plInfo.size.height
838 };
839 PostProc::ValidCropValue(opts_.CropRect, size);
840 ret = UpdatePixelMapInfo(opts_, plInfo, pixelMap);
841 if (ret != SUCCESS) {
842 IMAGE_LOGE("[ImageSource]update pixelmap info error (image index:%{public}u), ret:%{public}u.",
843 index, ret);
844 return ret;
845 }
846 incrementalRecordIter->second.IncrementalState = ImageDecodingState::IMAGE_DECODING;
847 }
848 if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_DECODING) {
849 ret = DoIncrementalDecoding(index, opts_, pixelMap, incrementalRecordIter->second);
850 decodeProgress = incrementalRecordIter->second.decodingProgress;
851 state = incrementalRecordIter->second.IncrementalState;
852 if (isIncrementalCompleted_) {
853 PostProc postProc;
854 ret = postProc.DecodePostProc(opts_, pixelMap);
855 if (state == ImageDecodingState::IMAGE_DECODED) {
856 auto iter = decodeEventMap_.find((int)DecodeEvent::EVENT_COMPLETE_DECODE);
857 if (iter == decodeEventMap_.end()) {
858 decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_COMPLETE_DECODE, 1));
859 for (auto listener : decodeListeners_) {
860 guard.unlock();
861 listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
862 guard.lock();
863 }
864 }
865 }
866 }
867 return ret;
868 }
869
870 // IMAGE_ERROR or IMAGE_DECODED.
871 state = incrementalRecordIter->second.IncrementalState;
872 decodeProgress = incrementalRecordIter->second.decodingProgress;
873 if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_ERROR) {
874 IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on incremental decoding.",
875 incrementalRecordIter->second.IncrementalState);
876 return ERR_IMAGE_DECODE_ABNORMAL;
877 }
878 return SUCCESS;
879 }
880
DetachIncrementalDecoding(PixelMap & pixelMap)881 void ImageSource::DetachIncrementalDecoding(PixelMap &pixelMap)
882 {
883 std::lock_guard<std::mutex> guard(decodingMutex_);
884 auto iter = incDecodingMap_.find(&pixelMap);
885 if (iter == incDecodingMap_.end()) {
886 return;
887 }
888
889 if (mainDecoder_ == nullptr) {
890 // return back the decoder to mainDecoder_.
891 mainDecoder_ = std::move(iter->second.decoder);
892 iter->second.decoder = nullptr;
893 }
894 incDecodingMap_.erase(iter);
895 }
896
UpdateData(const uint8_t * data,uint32_t size,bool isCompleted)897 uint32_t ImageSource::UpdateData(const uint8_t *data, uint32_t size, bool isCompleted)
898 {
899 if (sourceStreamPtr_ == nullptr) {
900 IMAGE_LOGE("[ImageSource]image source update data, source stream is null.");
901 return ERR_IMAGE_INVALID_PARAMETER;
902 }
903 std::lock_guard<std::mutex> guard(decodingMutex_);
904 if (isCompleted) {
905 isIncrementalCompleted_ = isCompleted;
906 }
907 return sourceStreamPtr_->UpdateData(data, size, isCompleted);
908 }
909
GetDecodeEvent()910 DecodeEvent ImageSource::GetDecodeEvent()
911 {
912 return decodeEvent_;
913 }
914
GetImageInfo(uint32_t index,ImageInfo & imageInfo)915 uint32_t ImageSource::GetImageInfo(uint32_t index, ImageInfo &imageInfo)
916 {
917 ImageTrace imageTrace("GetImageInfo by index");
918 uint32_t ret = SUCCESS;
919 std::unique_lock<std::mutex> guard(decodingMutex_);
920 auto iter = GetValidImageStatus(index, ret);
921 if (iter == imageStatusMap_.end()) {
922 guard.unlock();
923 IMAGE_LOGE("[ImageSource]get valid image status fail on get image info, ret:%{public}u.", ret);
924 return ret;
925 }
926 ImageInfo &info = (iter->second).imageInfo;
927 if (info.size.width == 0 || info.size.height == 0) {
928 IMAGE_LOGE("[ImageSource]get the image size fail on get image info, width:%{public}d,"
929 "height:%{public}d.", info.size.width, info.size.height);
930 return ERR_IMAGE_DECODE_FAILED;
931 }
932
933 imageInfo = info;
934 return SUCCESS;
935 }
936
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,const std::string & path)937 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
938 const std::string &value, const std::string &path)
939 {
940 std::unique_lock<std::mutex> guard(decodingMutex_);
941 uint32_t ret;
942 auto iter = GetValidImageStatus(0, ret);
943 if (iter == imageStatusMap_.end()) {
944 IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
945 return ret;
946 }
947 ret = mainDecoder_->ModifyImageProperty(index, key, value, path);
948 if (ret != SUCCESS) {
949 IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
950 return ret;
951 }
952 return SUCCESS;
953 }
954
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,const int fd)955 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
956 const std::string &value, const int fd)
957 {
958 std::unique_lock<std::mutex> guard(decodingMutex_);
959 uint32_t ret;
960 auto iter = GetValidImageStatus(0, ret);
961 if (iter == imageStatusMap_.end()) {
962 IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
963 return ret;
964 }
965 ret = mainDecoder_->ModifyImageProperty(index, key, value, fd);
966 if (ret != SUCCESS) {
967 IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
968 return ret;
969 }
970 return SUCCESS;
971 }
972
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,uint8_t * data,uint32_t size)973 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
974 const std::string &value, uint8_t *data, uint32_t size)
975 {
976 std::unique_lock<std::mutex> guard(decodingMutex_);
977 uint32_t ret;
978 auto iter = GetValidImageStatus(0, ret);
979 if (iter == imageStatusMap_.end()) {
980 IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
981 return ret;
982 }
983 ret = mainDecoder_->ModifyImageProperty(index, key, value, data, size);
984 if (ret != SUCCESS) {
985 IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
986 return ret;
987 }
988 return SUCCESS;
989 }
990
GetImagePropertyInt(uint32_t index,const std::string & key,int32_t & value)991 uint32_t ImageSource::GetImagePropertyInt(uint32_t index, const std::string &key, int32_t &value)
992 {
993 std::unique_lock<std::mutex> guard(decodingMutex_);
994 uint32_t ret;
995 auto iter = GetValidImageStatus(0, ret);
996 if (iter == imageStatusMap_.end()) {
997 IMAGE_LOGE("[ImageSource]get valid image status fail on get image property, ret:%{public}u.", ret);
998 return ret;
999 }
1000
1001 ret = mainDecoder_->GetImagePropertyInt(index, key, value);
1002 if (ret != SUCCESS) {
1003 IMAGE_LOGD("[ImageSource] GetImagePropertyInt fail, ret:%{public}u", ret);
1004 return ret;
1005 }
1006 return SUCCESS;
1007 }
1008
GetImagePropertyString(uint32_t index,const std::string & key,std::string & value)1009 uint32_t ImageSource::GetImagePropertyString(uint32_t index, const std::string &key, std::string &value)
1010 {
1011 std::unique_lock<std::mutex> guard(decodingMutex_);
1012 uint32_t ret;
1013 auto iter = GetValidImageStatus(0, ret);
1014 if (iter == imageStatusMap_.end()) {
1015 IMAGE_LOGE("[ImageSource]get valid image status fail on get image property, ret:%{public}u.", ret);
1016 return ret;
1017 }
1018 ret = mainDecoder_->GetImagePropertyString(index, key, value);
1019 if (ret != SUCCESS) {
1020 IMAGE_LOGD("[ImageSource] GetImagePropertyString fail, ret:%{public}u", ret);
1021 return ret;
1022 }
1023 return SUCCESS;
1024 }
GetSourceInfo(uint32_t & errorCode)1025 const SourceInfo &ImageSource::GetSourceInfo(uint32_t &errorCode)
1026 {
1027 std::lock_guard<std::mutex> guard(decodingMutex_);
1028 if (IsSpecialYUV()) {
1029 return sourceInfo_;
1030 }
1031 errorCode = DecodeSourceInfo(true);
1032 return sourceInfo_;
1033 }
1034
RegisterListener(PeerListener * listener)1035 void ImageSource::RegisterListener(PeerListener *listener)
1036 {
1037 if (listener == nullptr) {
1038 return;
1039 }
1040 std::lock_guard<std::mutex> guard(listenerMutex_);
1041 listeners_.insert(listener);
1042 }
1043
UnRegisterListener(PeerListener * listener)1044 void ImageSource::UnRegisterListener(PeerListener *listener)
1045 {
1046 if (listener == nullptr) {
1047 return;
1048 }
1049 std::lock_guard<std::mutex> guard(listenerMutex_);
1050 auto iter = listeners_.find(listener);
1051 if (iter != listeners_.end()) {
1052 listeners_.erase(iter);
1053 }
1054 }
1055
AddDecodeListener(DecodeListener * listener)1056 void ImageSource::AddDecodeListener(DecodeListener *listener)
1057 {
1058 if (listener == nullptr) {
1059 IMAGE_LOGE("AddDecodeListener listener null");
1060 return;
1061 }
1062 std::lock_guard<std::mutex> guard(listenerMutex_);
1063 decodeListeners_.insert(listener);
1064 }
1065
RemoveDecodeListener(DecodeListener * listener)1066 void ImageSource::RemoveDecodeListener(DecodeListener *listener)
1067 {
1068 if (listener == nullptr) {
1069 IMAGE_LOGE("RemoveDecodeListener listener null");
1070 return;
1071 }
1072 std::lock_guard<std::mutex> guard(listenerMutex_);
1073 auto iter = decodeListeners_.find(listener);
1074 if (iter != decodeListeners_.end()) {
1075 decodeListeners_.erase(iter);
1076 }
1077 }
1078
~ImageSource()1079 ImageSource::~ImageSource()
1080 {
1081 IMAGE_LOGD("ImageSource destructor enter");
1082 std::lock_guard<std::mutex> guard(listenerMutex_);
1083 for (const auto &listener : listeners_) {
1084 listener->OnPeerDestory();
1085 }
1086 }
1087
IsStreamCompleted()1088 bool ImageSource::IsStreamCompleted()
1089 {
1090 std::lock_guard<std::mutex> guard(decodingMutex_);
1091 return sourceStreamPtr_->IsStreamCompleted();
1092 }
1093
1094 // ------------------------------- private method -------------------------------
ImageSource(unique_ptr<SourceStream> && stream,const SourceOptions & opts)1095 ImageSource::ImageSource(unique_ptr<SourceStream> &&stream, const SourceOptions &opts)
1096 : sourceStreamPtr_(stream.release())
1097 {
1098 sourceInfo_.baseDensity = opts.baseDensity;
1099 sourceOptions_.baseDensity = opts.baseDensity;
1100 sourceOptions_.pixelFormat = opts.pixelFormat;
1101 sourceOptions_.size.width = opts.size.width;
1102 sourceOptions_.size.height = opts.size.height;
1103
1104 // use format hint in svg format for the performance purpose
1105 if (opts.formatHint == InnerFormat::SVG_FORMAT) {
1106 sourceInfo_.encodedFormat = opts.formatHint;
1107 sourceOptions_.formatHint = opts.formatHint;
1108 }
1109 imageId_ = GetNowTimeMicroSeconds();
1110 }
1111
InitClass()1112 ImageSource::FormatAgentMap ImageSource::InitClass()
1113 {
1114 vector<ClassInfo> classInfos;
1115 pluginServer_.PluginServerGetClassInfo<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, classInfos);
1116 set<string> formats;
1117 for (auto &info : classInfos) {
1118 auto &capabilities = info.capabilities;
1119 auto iter = capabilities.find(IMAGE_ENCODE_FORMAT);
1120 if (iter == capabilities.end()) {
1121 continue;
1122 }
1123
1124 AttrData &attr = iter->second;
1125 string format;
1126 if (SUCCESS != attr.GetValue(format)) {
1127 IMAGE_LOGE("[ImageSource]attr data get format:[%{public}s] failed.", format.c_str());
1128 continue;
1129 }
1130 formats.insert(move(format));
1131 }
1132
1133 FormatAgentMap tempAgentMap;
1134 AbsImageFormatAgent *formatAgent = nullptr;
1135 for (auto format : formats) {
1136 map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(format) } };
1137 formatAgent =
1138 pluginServer_.CreateObject<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, capabilities);
1139 if (formatAgent == nullptr) {
1140 continue;
1141 }
1142 tempAgentMap.insert(FormatAgentMap::value_type(std::move(format), formatAgent));
1143 }
1144 return tempAgentMap;
1145 }
1146
CheckEncodedFormat(AbsImageFormatAgent & agent)1147 uint32_t ImageSource::CheckEncodedFormat(AbsImageFormatAgent &agent)
1148 {
1149 uint32_t size = agent.GetHeaderSize();
1150 ImagePlugin::DataStreamBuffer outData;
1151 uint32_t res = GetData(outData, size);
1152 if (res != SUCCESS) {
1153 return res;
1154 }
1155 if (!agent.CheckFormat(outData.inputStreamBuffer, size)) {
1156 IMAGE_LOGE("[ImageSource]check mismatched format :%{public}s.", agent.GetFormatType().c_str());
1157 return ERR_IMAGE_MISMATCHED_FORMAT;
1158 }
1159 return SUCCESS;
1160 }
1161
GetData(ImagePlugin::DataStreamBuffer & outData,size_t size)1162 uint32_t ImageSource::GetData(ImagePlugin::DataStreamBuffer &outData, size_t size)
1163 {
1164 if (sourceStreamPtr_ == nullptr) {
1165 IMAGE_LOGE("[ImageSource]check image format, source stream is null.");
1166 return ERR_IMAGE_INVALID_PARAMETER;
1167 }
1168 if (!sourceStreamPtr_->Peek(size, outData)) {
1169 IMAGE_LOGE("[ImageSource]stream peek the data fail, desiredSize:%{public}zu", size);
1170 return ERR_IMAGE_SOURCE_DATA;
1171 }
1172 if (outData.inputStreamBuffer == nullptr || outData.dataSize < size) {
1173 IMAGE_LOGE("[ImageSource]the outData is incomplete.");
1174 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
1175 }
1176 return SUCCESS;
1177 }
1178
CheckFormatHint(const string & formatHint,FormatAgentMap::iterator & formatIter)1179 uint32_t ImageSource::CheckFormatHint(const string &formatHint, FormatAgentMap::iterator &formatIter)
1180 {
1181 uint32_t ret = ERROR;
1182 formatIter = formatAgentMap_.find(formatHint);
1183 if (formatIter == formatAgentMap_.end()) {
1184 IMAGE_LOGE("[ImageSource]check input format fail.");
1185 return ret;
1186 }
1187 AbsImageFormatAgent *agent = formatIter->second;
1188 ret = CheckEncodedFormat(*agent);
1189 if (ret != SUCCESS) {
1190 if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1191 IMAGE_LOGE("[ImageSource]image source incomplete.");
1192 }
1193 return ret;
1194 }
1195 return SUCCESS;
1196 }
1197
DoCreateDecoder(std::string codecFormat,PluginServer & pluginServer,InputDataStream & sourceData,uint32_t & errorCode)1198 AbsImageDecoder *DoCreateDecoder(std::string codecFormat,
1199 PluginServer &pluginServer, InputDataStream &sourceData, uint32_t &errorCode)
1200 {
1201 map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(codecFormat) } };
1202 for (const auto &capability : capabilities) {
1203 std::string x = "undefined";
1204 capability.second.GetValue(x);
1205 IMAGE_LOGD("[ImageSource] capabilities [%{public}s],[%{public}s]",
1206 capability.first.c_str(), x.c_str());
1207 }
1208 auto decoder = pluginServer.CreateObject<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT, capabilities);
1209 if (decoder == nullptr) {
1210 IMAGE_LOGE("[ImageSource]failed to create decoder object.");
1211 errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
1212 return nullptr;
1213 }
1214 errorCode = SUCCESS;
1215 decoder->SetSource(sourceData);
1216 return decoder;
1217 }
1218
GetFormatExtended(string & format)1219 uint32_t ImageSource::GetFormatExtended(string &format)
1220 {
1221 if (mainDecoder_ != nullptr) {
1222 format = sourceInfo_.encodedFormat;
1223 return SUCCESS;
1224 }
1225
1226 if (sourceStreamPtr_ == nullptr) {
1227 IMAGE_LOGE("[ImageSource]sourceStreamPtr_ is null");
1228 return ERR_MEDIA_NULL_POINTER;
1229 }
1230
1231 auto imageType = sourceStreamPtr_->Tell();
1232 uint32_t errorCode = ERR_IMAGE_DECODE_ABNORMAL;
1233 auto codec = DoCreateDecoder(InnerFormat::IMAGE_EXTENDED_CODEC, pluginServer_, *sourceStreamPtr_,
1234 errorCode);
1235 if (errorCode != SUCCESS || codec == nullptr) {
1236 IMAGE_LOGE("[ImageSource]No extended decoder.");
1237 return errorCode;
1238 }
1239 const static string EXT_ENCODED_FORMAT_KEY = "EncodedFormat";
1240 auto decoderPtr = unique_ptr<AbsImageDecoder>(codec);
1241 if (decoderPtr == nullptr) {
1242 IMAGE_LOGE("[ImageSource]decoderPtr null");
1243 return ERR_MEDIA_NULL_POINTER;
1244 }
1245 ProgDecodeContext context;
1246 if (IsIncrementalSource() &&
1247 decoderPtr->PromoteIncrementalDecode(UINT32_MAX, context) == ERR_IMAGE_DATA_UNSUPPORT) {
1248 return ERR_IMAGE_DATA_UNSUPPORT;
1249 }
1250 errorCode = decoderPtr->GetImagePropertyString(FIRST_FRAME, EXT_ENCODED_FORMAT_KEY, format);
1251 if (errorCode != SUCCESS) {
1252 IMAGE_LOGE("[ImageSource]Extended get format failed %{public}d.", errorCode);
1253 return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
1254 }
1255
1256 if (!ImageSystemProperties::GetSkiaEnabled()) {
1257 IMAGE_LOGD("[ImageSource]Extended close SK decode");
1258 if (format != "image/gif") {
1259 sourceStreamPtr_->Seek(imageType);
1260 return ERR_MEDIA_DATA_UNSUPPORT;
1261 }
1262 }
1263 mainDecoder_ = std::move(decoderPtr);
1264 return errorCode;
1265 }
1266
GetEncodedFormat(const string & formatHint,string & format)1267 uint32_t ImageSource::GetEncodedFormat(const string &formatHint, string &format)
1268 {
1269 uint32_t ret;
1270 auto hintIter = formatAgentMap_.end();
1271 if (!formatHint.empty()) {
1272 ret = CheckFormatHint(formatHint, hintIter);
1273 if (ret == SUCCESS) {
1274 format = hintIter->first;
1275 IMAGE_LOGD("[ImageSource]check input image format success, format:%{public}s.", format.c_str());
1276 return SUCCESS;
1277 } else {
1278 IMAGE_LOGE("[ImageSource]checkFormatHint error, type: %{public}d", ret);
1279 return ret;
1280 }
1281 }
1282
1283 if (GetFormatExtended(format) == SUCCESS) {
1284 return SUCCESS;
1285 }
1286
1287 for (auto iter = formatAgentMap_.begin(); iter != formatAgentMap_.end(); ++iter) {
1288 string curFormat = iter->first;
1289 if (iter == hintIter || curFormat == InnerFormat::RAW_FORMAT) {
1290 continue; // has been checked before.
1291 }
1292 AbsImageFormatAgent *agent = iter->second;
1293 ret = CheckEncodedFormat(*agent);
1294 if (ret == ERR_IMAGE_MISMATCHED_FORMAT) {
1295 continue;
1296 } else if (ret == SUCCESS) {
1297 IMAGE_LOGI("[ImageSource]GetEncodedFormat success format :%{public}s.", iter->first.c_str());
1298 format = iter->first;
1299 return SUCCESS;
1300 } else {
1301 IMAGE_LOGE("[ImageSource]checkEncodedFormat error, type: %{public}d", ret);
1302 return ret;
1303 }
1304 }
1305
1306 // default return raw image, ERR_IMAGE_MISMATCHED_FORMAT case
1307 format = InnerFormat::RAW_FORMAT;
1308 IMAGE_LOGI("[ImageSource]image default to raw format.");
1309 return SUCCESS;
1310 }
1311
OnSourceRecognized(bool isAcquiredImageNum)1312 uint32_t ImageSource::OnSourceRecognized(bool isAcquiredImageNum)
1313 {
1314 uint32_t ret = InitMainDecoder();
1315 if (ret != SUCCESS) {
1316 sourceInfo_.state = SourceInfoState::UNSUPPORTED_FORMAT;
1317 decodeState_ = SourceDecodingState::UNSUPPORTED_FORMAT;
1318 IMAGE_LOGE("[ImageSource]image decode error, ret:[%{public}u].", ret);
1319 return ret;
1320 }
1321
1322 // for raw image, we need check the original format after decoder initialzation
1323 string value;
1324 ret = mainDecoder_->GetImagePropertyString(0, ACTUAL_IMAGE_ENCODED_FORMAT, value);
1325 if (ret == SUCCESS) {
1326 // update new format
1327 sourceInfo_.encodedFormat = value;
1328 IMAGE_LOGI("[ImageSource] update new format, value:%{public}s", value.c_str());
1329 }
1330
1331 if (isAcquiredImageNum) {
1332 ret = mainDecoder_->GetTopLevelImageNum(sourceInfo_.topLevelImageNum);
1333 if (ret != SUCCESS) {
1334 if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1335 sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
1336 IMAGE_LOGE("[ImageSource]image source data incomplete.");
1337 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
1338 }
1339 sourceInfo_.state = SourceInfoState::FILE_INFO_ERROR;
1340 decodeState_ = SourceDecodingState::FILE_INFO_ERROR;
1341 IMAGE_LOGE("[ImageSource]image source error.");
1342 return ret;
1343 }
1344 }
1345 sourceInfo_.state = SourceInfoState::FILE_INFO_PARSED;
1346 decodeState_ = SourceDecodingState::FILE_INFO_DECODED;
1347 return SUCCESS;
1348 }
1349
OnSourceUnresolved()1350 uint32_t ImageSource::OnSourceUnresolved()
1351 {
1352 string formatResult;
1353 if (!isAstc_.has_value()) {
1354 ImagePlugin::DataStreamBuffer outData;
1355 uint32_t res = GetData(outData, ASTC_HEADER_SIZE);
1356 if (res == SUCCESS) {
1357 isAstc_ = IsASTC(outData.inputStreamBuffer, outData.dataSize);
1358 }
1359 }
1360 if (isAstc_.has_value() && isAstc_.value()) {
1361 formatResult = InnerFormat::ASTC_FORMAT;
1362 } else {
1363 auto ret = GetEncodedFormat(sourceInfo_.encodedFormat, formatResult);
1364 if (ret != SUCCESS) {
1365 if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1366 IMAGE_LOGE("[ImageSource]image source incomplete.");
1367 sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
1368 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
1369 } else if (ret == ERR_IMAGE_UNKNOWN_FORMAT) {
1370 IMAGE_LOGE("[ImageSource]image unknown format.");
1371 sourceInfo_.state = SourceInfoState::UNKNOWN_FORMAT;
1372 decodeState_ = SourceDecodingState::UNKNOWN_FORMAT;
1373 return ERR_IMAGE_UNKNOWN_FORMAT;
1374 }
1375 sourceInfo_.state = SourceInfoState::SOURCE_ERROR;
1376 decodeState_ = SourceDecodingState::SOURCE_ERROR;
1377 IMAGE_LOGE("[ImageSource]image source error.");
1378 return ret;
1379 }
1380 }
1381 sourceInfo_.encodedFormat = formatResult;
1382 decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
1383 return SUCCESS;
1384 }
1385
GetSourceDecodingState(SourceDecodingState decodeState_)1386 uint32_t GetSourceDecodingState(SourceDecodingState decodeState_)
1387 {
1388 uint32_t ret = SUCCESS;
1389 switch (decodeState_) {
1390 case SourceDecodingState::SOURCE_ERROR: {
1391 ret = ERR_IMAGE_SOURCE_DATA;
1392 break;
1393 }
1394 case SourceDecodingState::UNKNOWN_FORMAT: {
1395 ret = ERR_IMAGE_UNKNOWN_FORMAT;
1396 break;
1397 }
1398 case SourceDecodingState::UNSUPPORTED_FORMAT: {
1399 ret = ERR_IMAGE_PLUGIN_CREATE_FAILED;
1400 break;
1401 }
1402 case SourceDecodingState::FILE_INFO_ERROR: {
1403 ret = ERR_IMAGE_DECODE_FAILED;
1404 break;
1405 }
1406 default: {
1407 ret = ERROR;
1408 break;
1409 }
1410 }
1411 return ret;
1412 }
1413
DecodeSourceInfo(bool isAcquiredImageNum)1414 uint32_t ImageSource::DecodeSourceInfo(bool isAcquiredImageNum)
1415 {
1416 uint32_t ret = SUCCESS;
1417 if (decodeState_ >= SourceDecodingState::FILE_INFO_DECODED) {
1418 if (isAcquiredImageNum) {
1419 decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
1420 } else {
1421 return SUCCESS;
1422 }
1423 }
1424 if (decodeState_ == SourceDecodingState::UNRESOLVED) {
1425 ret = OnSourceUnresolved();
1426 if (ret != SUCCESS) {
1427 IMAGE_LOGE("[ImageSource]unresolved source: check format failed, ret:[%{public}d].", ret);
1428 return ret;
1429 }
1430 }
1431 if (decodeState_ == SourceDecodingState::FORMAT_RECOGNIZED) {
1432 if (sourceInfo_.encodedFormat == InnerFormat::ASTC_FORMAT) {
1433 sourceInfo_.state = SourceInfoState::FILE_INFO_PARSED;
1434 decodeState_ = SourceDecodingState::FILE_INFO_DECODED;
1435 } else {
1436 ret = OnSourceRecognized(isAcquiredImageNum);
1437 if (ret != SUCCESS) {
1438 IMAGE_LOGE("[ImageSource]recognized source: get source info failed, ret:[%{public}d].", ret);
1439 return ret;
1440 }
1441 }
1442 return SUCCESS;
1443 }
1444 IMAGE_LOGE("[ImageSource]invalid source state %{public}d on decode source info.", decodeState_);
1445 ret = GetSourceDecodingState(decodeState_);
1446 return ret;
1447 }
1448
DecodeImageInfo(uint32_t index,ImageStatusMap::iterator & iter)1449 uint32_t ImageSource::DecodeImageInfo(uint32_t index, ImageStatusMap::iterator &iter)
1450 {
1451 uint32_t ret = DecodeSourceInfo(false);
1452 if (ret != SUCCESS) {
1453 IMAGE_LOGE("[ImageSource]decode the image fail, ret:%{public}d.", ret);
1454 return ret;
1455 }
1456 if (sourceInfo_.encodedFormat == InnerFormat::ASTC_FORMAT) {
1457 ASTCInfo astcInfo;
1458 if (GetASTCInfo(sourceStreamPtr_->GetDataPtr(), sourceStreamPtr_->GetStreamSize(), astcInfo)) {
1459 ImageDecodingStatus imageStatus;
1460 imageStatus.imageInfo.size = astcInfo.size;
1461 imageStatus.imageState = ImageDecodingState::BASE_INFO_PARSED;
1462 auto result = imageStatusMap_.insert(ImageStatusMap::value_type(index, imageStatus));
1463 iter = result.first;
1464 return SUCCESS;
1465 } else {
1466 IMAGE_LOGE("[ImageSource] decode astc image info failed.");
1467 return ERR_IMAGE_DECODE_FAILED;
1468 }
1469 }
1470 if (mainDecoder_ == nullptr) {
1471 IMAGE_LOGE("[ImageSource]get image size, image decode plugin is null.");
1472 return ERR_IMAGE_PLUGIN_CREATE_FAILED;
1473 }
1474 ImagePlugin::PlSize size;
1475 ret = mainDecoder_->GetImageSize(index, size);
1476 if (ret == SUCCESS) {
1477 ImageDecodingStatus imageStatus;
1478 imageStatus.imageInfo.size.width = size.width;
1479 imageStatus.imageInfo.size.height = size.height;
1480 imageStatus.imageState = ImageDecodingState::BASE_INFO_PARSED;
1481 auto result = imageStatusMap_.insert(ImageStatusMap::value_type(index, imageStatus));
1482 iter = result.first;
1483 return SUCCESS;
1484 } else if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1485 IMAGE_LOGE("[ImageSource]source data incomplete.");
1486 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
1487 } else {
1488 ImageDecodingStatus status;
1489 status.imageState = ImageDecodingState::BASE_INFO_ERROR;
1490 auto errorResult = imageStatusMap_.insert(ImageStatusMap::value_type(index, status));
1491 iter = errorResult.first;
1492 IMAGE_LOGE("[ImageSource]decode the image info fail.");
1493 return ERR_IMAGE_DECODE_FAILED;
1494 }
1495 }
1496
InitMainDecoder()1497 uint32_t ImageSource::InitMainDecoder()
1498 {
1499 if (mainDecoder_ != nullptr) {
1500 return SUCCESS;
1501 }
1502 uint32_t result = SUCCESS;
1503 mainDecoder_ = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(result));
1504 return result;
1505 }
1506
CreateDecoder(uint32_t & errorCode)1507 AbsImageDecoder *ImageSource::CreateDecoder(uint32_t &errorCode)
1508 {
1509 // in normal mode, we can get actual encoded format to the user
1510 // but we need transfer to skia codec for adaption, "image/x-skia"
1511 std::string encodedFormat = sourceInfo_.encodedFormat;
1512 if (opts_.sampleSize != 1) {
1513 encodedFormat = InnerFormat::EXTENDED_FORMAT;
1514 }
1515 return DoCreateDecoder(encodedFormat, pluginServer_, *sourceStreamPtr_, errorCode);
1516 }
1517
GetDefaultPixelFormat(const PixelFormat desired,PlPixelFormat & out,MemoryUsagePreference preference)1518 static void GetDefaultPixelFormat(const PixelFormat desired, PlPixelFormat& out,
1519 MemoryUsagePreference preference)
1520 {
1521 if (desired != PixelFormat::UNKNOWN) {
1522 auto formatPair = PIXEL_FORMAT_MAP.find(desired);
1523 if (formatPair != PIXEL_FORMAT_MAP.end() && formatPair->second != PlPixelFormat::UNKNOWN) {
1524 out = formatPair->second;
1525 return;
1526 }
1527 }
1528 out = (preference == MemoryUsagePreference::LOW_RAM)?PlPixelFormat::RGB_565:PlPixelFormat::RGBA_8888;
1529 }
1530
SetDecodeOptions(std::unique_ptr<AbsImageDecoder> & decoder,uint32_t index,const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo)1531 uint32_t ImageSource::SetDecodeOptions(std::unique_ptr<AbsImageDecoder> &decoder,
1532 uint32_t index, const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo)
1533 {
1534 PlPixelFormat plDesiredFormat;
1535 GetDefaultPixelFormat(opts.desiredPixelFormat, plDesiredFormat, preference_);
1536 PixelDecodeOptions plOptions;
1537 CopyOptionsToPlugin(opts, plOptions);
1538 plOptions.desiredPixelFormat = plDesiredFormat;
1539 uint32_t ret = decoder->SetDecodeOptions(index, plOptions, plInfo);
1540 if (ret != SUCCESS) {
1541 IMAGE_LOGE("[ImageSource]decoder plugin set decode options fail (image index:%{public}u),"
1542 "ret:%{public}u.", index, ret);
1543 return ret;
1544 }
1545 auto iter = imageStatusMap_.find(index);
1546 if (iter != imageStatusMap_.end()) {
1547 ImageInfo &info = (iter->second).imageInfo;
1548 IMAGE_LOGD("[ImageSource]SetDecodeOptions plInfo.pixelFormat %{public}d", plInfo.pixelFormat);
1549
1550 PlPixelFormat format = plInfo.pixelFormat;
1551 auto find_item = std::find_if(PIXEL_FORMAT_MAP.begin(), PIXEL_FORMAT_MAP.end(),
1552 [format](const std::map<PixelFormat, PlPixelFormat>::value_type item) {
1553 return item.second == format;
1554 });
1555 if (find_item != PIXEL_FORMAT_MAP.end()) {
1556 info.pixelFormat = (*find_item).first;
1557 }
1558 IMAGE_LOGD("[ImageSource]SetDecodeOptions info.pixelFormat %{public}d", info.pixelFormat);
1559 }
1560 return SUCCESS;
1561 }
1562
UpdatePixelMapInfo(const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo,PixelMap & pixelMap)1563 uint32_t ImageSource::UpdatePixelMapInfo(const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo,
1564 PixelMap &pixelMap)
1565 {
1566 return UpdatePixelMapInfo(opts, plInfo, pixelMap, INT_ZERO);
1567 }
UpdatePixelMapInfo(const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo,PixelMap & pixelMap,int32_t fitDensity,bool isReUsed)1568 uint32_t ImageSource::UpdatePixelMapInfo(const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo,
1569 PixelMap &pixelMap, int32_t fitDensity, bool isReUsed)
1570 {
1571 pixelMap.SetEditable(opts.editable);
1572
1573 ImageInfo info;
1574 info.baseDensity = sourceInfo_.baseDensity;
1575 if (fitDensity != INT_ZERO) {
1576 info.baseDensity = fitDensity;
1577 }
1578 info.size.width = plInfo.size.width;
1579 info.size.height = plInfo.size.height;
1580 info.pixelFormat = static_cast<PixelFormat>(plInfo.pixelFormat);
1581 info.alphaType = static_cast<AlphaType>(plInfo.alphaType);
1582 return pixelMap.SetImageInfo(info, isReUsed);
1583 }
1584
CopyOptionsToPlugin(const DecodeOptions & opts,PixelDecodeOptions & plOpts)1585 void ImageSource::CopyOptionsToPlugin(const DecodeOptions &opts, PixelDecodeOptions &plOpts)
1586 {
1587 plOpts.CropRect.left = opts.CropRect.left;
1588 plOpts.CropRect.top = opts.CropRect.top;
1589 plOpts.CropRect.width = opts.CropRect.width;
1590 plOpts.CropRect.height = opts.CropRect.height;
1591 plOpts.desiredSize.width = opts.desiredSize.width;
1592 plOpts.desiredSize.height = opts.desiredSize.height;
1593 plOpts.rotateDegrees = opts.rotateDegrees;
1594 plOpts.sampleSize = opts.sampleSize;
1595 auto formatSearch = PIXEL_FORMAT_MAP.find(opts.desiredPixelFormat);
1596 plOpts.desiredPixelFormat =
1597 (formatSearch != PIXEL_FORMAT_MAP.end()) ? formatSearch->second : PlPixelFormat::RGBA_8888;
1598 auto colorSearch = COLOR_SPACE_MAP.find(opts.desiredColorSpace);
1599 plOpts.desiredColorSpace = (colorSearch != COLOR_SPACE_MAP.end()) ? colorSearch->second : PlColorSpace::UNKNOWN;
1600 plOpts.allowPartialImage = opts.allowPartialImage;
1601 plOpts.editable = opts.editable;
1602 if (opts.SVGOpts.fillColor.isValidColor) {
1603 plOpts.plFillColor.isValidColor = opts.SVGOpts.fillColor.isValidColor;
1604 plOpts.plFillColor.color = opts.SVGOpts.fillColor.color;
1605 }
1606 if (opts.SVGOpts.SVGResize.isValidPercentage) {
1607 plOpts.plSVGResize.isValidPercentage = opts.SVGOpts.SVGResize.isValidPercentage;
1608 plOpts.plSVGResize.resizePercentage = opts.SVGOpts.SVGResize.resizePercentage;
1609 }
1610 plOpts.plDesiredColorSpace = opts.desiredColorSpaceInfo;
1611 }
1612
CopyOptionsToProcOpts(const DecodeOptions & opts,DecodeOptions & procOpts,PixelMap & pixelMap)1613 void ImageSource::CopyOptionsToProcOpts(const DecodeOptions &opts, DecodeOptions &procOpts, PixelMap &pixelMap)
1614 {
1615 procOpts.fitDensity = opts.fitDensity;
1616 procOpts.CropRect.left = opts.CropRect.left;
1617 procOpts.CropRect.top = opts.CropRect.top;
1618 procOpts.CropRect.width = opts.CropRect.width;
1619 procOpts.CropRect.height = opts.CropRect.height;
1620 procOpts.desiredSize.width = opts.desiredSize.width;
1621 procOpts.desiredSize.height = opts.desiredSize.height;
1622 procOpts.rotateDegrees = opts.rotateDegrees;
1623 procOpts.sampleSize = opts.sampleSize;
1624 procOpts.desiredPixelFormat = opts.desiredPixelFormat;
1625 if (opts.allocatorType == AllocatorType::DEFAULT) {
1626 procOpts.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
1627 } else {
1628 procOpts.allocatorType = opts.allocatorType;
1629 }
1630 procOpts.desiredColorSpace = opts.desiredColorSpace;
1631 procOpts.allowPartialImage = opts.allowPartialImage;
1632 procOpts.editable = opts.editable;
1633 // we need preference_ when post processing
1634 procOpts.preference = preference_;
1635 }
1636
GetValidImageStatus(uint32_t index,uint32_t & errorCode)1637 ImageSource::ImageStatusMap::iterator ImageSource::GetValidImageStatus(uint32_t index, uint32_t &errorCode)
1638 {
1639 auto iter = imageStatusMap_.find(index);
1640 if (iter == imageStatusMap_.end()) {
1641 errorCode = DecodeImageInfo(index, iter);
1642 if (errorCode != SUCCESS) {
1643 IMAGE_LOGE("[ImageSource]image info decode fail, ret:%{public}u.", errorCode);
1644 return imageStatusMap_.end();
1645 }
1646 } else if (iter->second.imageState < ImageDecodingState::BASE_INFO_PARSED) {
1647 IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on get image status.", iter->second.imageState);
1648 errorCode = ERR_IMAGE_DECODE_FAILED;
1649 return imageStatusMap_.end();
1650 }
1651 errorCode = SUCCESS;
1652 return iter;
1653 }
1654
AddIncrementalContext(PixelMap & pixelMap,IncrementalRecordMap::iterator & iterator)1655 uint32_t ImageSource::AddIncrementalContext(PixelMap &pixelMap, IncrementalRecordMap::iterator &iterator)
1656 {
1657 uint32_t ret = SUCCESS;
1658 IncrementalDecodingContext context;
1659 if (mainDecoder_ != nullptr) {
1660 // borrowed decoder from the mainDecoder_.
1661 context.decoder = std::move(mainDecoder_);
1662 } else {
1663 context.decoder = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(ret));
1664 }
1665 if (context.decoder == nullptr) {
1666 IMAGE_LOGE("[ImageSource]failed to create decoder on add incremental context, ret:%{public}u.", ret);
1667 return ret;
1668 }
1669 // mainDecoder has parsed base info in DecodeImageInfo();
1670 context.IncrementalState = ImageDecodingState::BASE_INFO_PARSED;
1671 auto result = incDecodingMap_.insert(IncrementalRecordMap::value_type(&pixelMap, std::move(context)));
1672 iterator = result.first;
1673 return SUCCESS;
1674 }
1675
DoIncrementalDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,IncrementalDecodingContext & recordContext)1676 uint32_t ImageSource::DoIncrementalDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
1677 IncrementalDecodingContext &recordContext)
1678 {
1679 IMAGE_LOGD("[ImageSource]do incremental decoding: begin.");
1680 uint8_t *pixelAddr = static_cast<uint8_t *>(pixelMap.GetWritablePixels());
1681 ProgDecodeContext context;
1682 context.decodeContext.pixelsBuffer.buffer = pixelAddr;
1683 uint32_t ret = recordContext.decoder->PromoteIncrementalDecode(index, context);
1684 if (context.decodeContext.pixelsBuffer.buffer != nullptr && pixelAddr == nullptr) {
1685 pixelMap.SetPixelsAddr(context.decodeContext.pixelsBuffer.buffer, context.decodeContext.pixelsBuffer.context,
1686 context.decodeContext.pixelsBuffer.bufferSize, context.decodeContext.allocatorType,
1687 context.decodeContext.freeFunc);
1688 }
1689 IMAGE_LOGD("[ImageSource]do incremental decoding progress:%{public}u.", context.totalProcessProgress);
1690 recordContext.decodingProgress = context.totalProcessProgress;
1691 if (ret != SUCCESS && ret != ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1692 recordContext.IncrementalState = ImageDecodingState::IMAGE_ERROR;
1693 IMAGE_LOGE("[ImageSource]do incremental decoding source fail, ret:%{public}u.", ret);
1694 return ret;
1695 }
1696 if (ret == SUCCESS) {
1697 recordContext.IncrementalState = ImageDecodingState::IMAGE_DECODED;
1698 IMAGE_LOGI("[ImageSource]do incremental decoding success.");
1699 }
1700 return ret;
1701 }
1702
GetNinePatchInfo() const1703 const NinePatchInfo &ImageSource::GetNinePatchInfo() const
1704 {
1705 return ninePatchInfo_;
1706 }
1707
SetMemoryUsagePreference(const MemoryUsagePreference preference)1708 void ImageSource::SetMemoryUsagePreference(const MemoryUsagePreference preference)
1709 {
1710 preference_ = preference;
1711 }
1712
GetMemoryUsagePreference()1713 MemoryUsagePreference ImageSource::GetMemoryUsagePreference()
1714 {
1715 return preference_;
1716 }
1717
GetFilterArea(const int & privacyType,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1718 uint32_t ImageSource::GetFilterArea(const int &privacyType, std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1719 {
1720 std::unique_lock<std::mutex> guard(decodingMutex_);
1721 uint32_t ret;
1722 auto iter = GetValidImageStatus(0, ret);
1723 if (iter == imageStatusMap_.end()) {
1724 IMAGE_LOGE("[ImageSource]get valid image status fail on get filter area, ret:%{public}u.", ret);
1725 return ret;
1726 }
1727 ret = mainDecoder_->GetFilterArea(privacyType, ranges);
1728 if (ret != SUCCESS) {
1729 IMAGE_LOGE("[ImageSource] GetFilterArea fail, ret:%{public}u", ret);
1730 return ret;
1731 }
1732 return SUCCESS;
1733 }
1734
SetIncrementalSource(const bool isIncrementalSource)1735 void ImageSource::SetIncrementalSource(const bool isIncrementalSource)
1736 {
1737 isIncrementalSource_ = isIncrementalSource;
1738 }
1739
IsIncrementalSource()1740 bool ImageSource::IsIncrementalSource()
1741 {
1742 return isIncrementalSource_;
1743 }
1744
GetFinalOutputStep(const DecodeOptions & opts,PixelMap & pixelMap,bool hasNinePatch)1745 FinalOutputStep ImageSource::GetFinalOutputStep(const DecodeOptions &opts, PixelMap &pixelMap, bool hasNinePatch)
1746 {
1747 ImageInfo info;
1748 pixelMap.GetImageInfo(info);
1749 ImageInfo dstImageInfo;
1750 dstImageInfo.size = opts.desiredSize;
1751 dstImageInfo.pixelFormat = opts.desiredPixelFormat;
1752 if (opts.desiredPixelFormat == PixelFormat::UNKNOWN) {
1753 if (preference_ == MemoryUsagePreference::LOW_RAM && info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
1754 dstImageInfo.pixelFormat = PixelFormat::RGB_565;
1755 } else {
1756 dstImageInfo.pixelFormat = PixelFormat::RGBA_8888;
1757 }
1758 }
1759 // decode use, this value may be changed by real pixelFormat
1760 if (pixelMap.GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) {
1761 dstImageInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
1762 } else {
1763 dstImageInfo.alphaType = pixelMap.GetAlphaType();
1764 }
1765 bool densityChange = HasDensityChange(opts, info, hasNinePatch);
1766 bool sizeChange = ImageSizeChange(pixelMap.GetWidth(), pixelMap.GetHeight(),
1767 opts.desiredSize.width, opts.desiredSize.height);
1768 bool rotateChange = !ImageUtils::FloatCompareZero(opts.rotateDegrees);
1769 bool convertChange = ImageConverChange(opts.CropRect, dstImageInfo, info);
1770 if (sizeChange) {
1771 return FinalOutputStep::SIZE_CHANGE;
1772 }
1773 if (densityChange) {
1774 return FinalOutputStep::DENSITY_CHANGE;
1775 }
1776 if (rotateChange) {
1777 return FinalOutputStep::ROTATE_CHANGE;
1778 }
1779 if (convertChange) {
1780 return FinalOutputStep::CONVERT_CHANGE;
1781 }
1782 return FinalOutputStep::NO_CHANGE;
1783 }
1784
HasDensityChange(const DecodeOptions & opts,ImageInfo & srcImageInfo,bool hasNinePatch)1785 bool ImageSource::HasDensityChange(const DecodeOptions &opts, ImageInfo &srcImageInfo, bool hasNinePatch)
1786 {
1787 return !hasNinePatch && (srcImageInfo.baseDensity > 0) &&
1788 (opts.fitDensity > 0) && (srcImageInfo.baseDensity != opts.fitDensity);
1789 }
1790
ImageSizeChange(int32_t width,int32_t height,int32_t desiredWidth,int32_t desiredHeight)1791 bool ImageSource::ImageSizeChange(int32_t width, int32_t height, int32_t desiredWidth, int32_t desiredHeight)
1792 {
1793 bool sizeChange = false;
1794 if (desiredWidth > 0 && desiredHeight > 0 && width > 0 && height > 0) {
1795 float scaleX = static_cast<float>(desiredWidth) / static_cast<float>(width);
1796 float scaleY = static_cast<float>(desiredHeight) / static_cast<float>(height);
1797 if ((fabs(scaleX - 1.0f) >= EPSILON) && (fabs(scaleY - 1.0f) >= EPSILON)) {
1798 sizeChange = true;
1799 }
1800 }
1801 return sizeChange;
1802 }
1803
ImageConverChange(const Rect & cropRect,ImageInfo & dstImageInfo,ImageInfo & srcImageInfo)1804 bool ImageSource::ImageConverChange(const Rect &cropRect, ImageInfo &dstImageInfo, ImageInfo &srcImageInfo)
1805 {
1806 bool hasPixelConvert = false;
1807 dstImageInfo.alphaType = ImageUtils::GetValidAlphaTypeByFormat(dstImageInfo.alphaType, dstImageInfo.pixelFormat);
1808 if (dstImageInfo.pixelFormat != srcImageInfo.pixelFormat || dstImageInfo.alphaType != srcImageInfo.alphaType) {
1809 hasPixelConvert = true;
1810 }
1811 CropValue value = PostProc::GetCropValue(cropRect, srcImageInfo.size);
1812 if (value == CropValue::NOCROP && !hasPixelConvert) {
1813 IMAGE_LOGD("[ImageSource]no need crop and pixel convert.");
1814 return false;
1815 } else if (value == CropValue::INVALID) {
1816 IMAGE_LOGE("[ImageSource]invalid corp region, top:%{public}d, left:%{public}d, "
1817 "width:%{public}d, height:%{public}d", cropRect.top, cropRect.left, cropRect.width, cropRect.height);
1818 return false;
1819 }
1820 return true;
1821 }
DecodeBase64(const uint8_t * data,uint32_t size)1822 unique_ptr<SourceStream> ImageSource::DecodeBase64(const uint8_t *data, uint32_t size)
1823 {
1824 if (size < IMAGE_URL_PREFIX.size() ||
1825 ::memcmp(data, IMAGE_URL_PREFIX.c_str(), IMAGE_URL_PREFIX.size()) != INT_ZERO) {
1826 IMAGE_LOGD("[ImageSource]Base64 image header mismatch.");
1827 return nullptr;
1828 }
1829 const char* data1 = reinterpret_cast<const char*>(data);
1830 auto sub = ::strstr(data1, BASE64_URL_PREFIX.c_str());
1831 if (sub == nullptr) {
1832 IMAGE_LOGI("[ImageSource]Base64 mismatch.");
1833 return nullptr;
1834 }
1835 sub = sub + BASE64_URL_PREFIX.size();
1836 uint32_t subSize = size - (sub - data1);
1837 IMAGE_LOGD("[ImageSource]Base64 image input: %{public}p, data: %{public}p, size %{public}u.",
1838 data, sub, subSize);
1839 #ifdef NEW_SKIA
1840 size_t outputLen = 0;
1841 SkBase64::Error error = SkBase64::Decode(sub, subSize, nullptr, &outputLen);
1842 if (error != SkBase64::Error::kNoError) {
1843 IMAGE_LOGE("[ImageSource]Base64 decode get out size failed.");
1844 return nullptr;
1845 }
1846
1847 sk_sp<SkData> resData = SkData::MakeUninitialized(outputLen);
1848 error = SkBase64::Decode(sub, subSize, resData->writable_data(), &outputLen);
1849 if (error != SkBase64::Error::kNoError) {
1850 IMAGE_LOGE("[ImageSource]Base64 decode get data failed.");
1851 return nullptr;
1852 }
1853 IMAGE_LOGD("[ImageSource][NewSkia]Create BufferSource from decoded base64 string.");
1854 auto imageData = static_cast<const uint8_t*>(resData->data());
1855 return BufferSourceStream::CreateSourceStream(imageData, resData->size());
1856 #else
1857 SkBase64 base64Decoder;
1858 if (base64Decoder.decode(sub, subSize) != SkBase64::kNoError) {
1859 IMAGE_LOGE("[ImageSource]base64 image decode failed!");
1860 return nullptr;
1861 }
1862 auto base64Data = base64Decoder.getData();
1863 const uint8_t* imageData = reinterpret_cast<uint8_t*>(base64Data);
1864 IMAGE_LOGD("[ImageSource]Create BufferSource from decoded base64 string.");
1865 auto result = BufferSourceStream::CreateSourceStream(imageData, base64Decoder.getDataSize());
1866 if (base64Data != nullptr) {
1867 delete[] base64Data;
1868 base64Data = nullptr;
1869 }
1870 return result;
1871 #endif
1872 }
1873
DecodeBase64(const string & data)1874 unique_ptr<SourceStream> ImageSource::DecodeBase64(const string &data)
1875 {
1876 return DecodeBase64(reinterpret_cast<const uint8_t*>(data.c_str()), data.size());
1877 }
1878
IsSpecialYUV()1879 bool ImageSource::IsSpecialYUV()
1880 {
1881 const bool isBufferSource = (sourceStreamPtr_ != nullptr)
1882 && (sourceStreamPtr_->GetStreamType() == ImagePlugin::BUFFER_SOURCE_TYPE);
1883 const bool isSizeValid = (sourceOptions_.size.width > 0) && (sourceOptions_.size.height > 0);
1884 const bool isYUV = (sourceOptions_.pixelFormat == PixelFormat::NV12)
1885 || (sourceOptions_.pixelFormat == PixelFormat::NV21);
1886 return (isBufferSource && isSizeValid && isYUV);
1887 }
1888
FloatToUint8(float f)1889 static inline uint8_t FloatToUint8(float f)
1890 {
1891 int data = static_cast<int>(f + 0.5f);
1892 if (data < 0) {
1893 data = 0;
1894 } else if (data > UINT8_MAX) {
1895 data = UINT8_MAX;
1896 }
1897 return static_cast<uint8_t>(data);
1898 }
1899
ConvertYUV420ToRGBA(uint8_t * data,uint32_t size,bool isSupportOdd,bool isAddUV,uint32_t & errorCode)1900 bool ImageSource::ConvertYUV420ToRGBA(uint8_t *data, uint32_t size,
1901 bool isSupportOdd, bool isAddUV, uint32_t &errorCode)
1902 {
1903 IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA IN srcPixelFormat:%{public}d, srcSize:(%{public}d,"
1904 "%{public}d)", sourceOptions_.pixelFormat, sourceOptions_.size.width, sourceOptions_.size.height);
1905 if ((!isSupportOdd) && (sourceOptions_.size.width & 1) == 1) {
1906 IMAGE_LOGE("[ImageSource]ConvertYUV420ToRGBA odd width, %{public}d", sourceOptions_.size.width);
1907 errorCode = ERR_IMAGE_DATA_UNSUPPORT;
1908 return false;
1909 }
1910
1911 const size_t width = sourceOptions_.size.width;
1912 const size_t height = sourceOptions_.size.height;
1913 const size_t uvwidth = (isSupportOdd && isAddUV) ? (width + (width & 1)) : width;
1914 const uint8_t *yuvPlane = sourceStreamPtr_->GetDataPtr();
1915 const size_t yuvSize = sourceStreamPtr_->GetStreamSize();
1916 const size_t ubase = width * height + ((sourceOptions_.pixelFormat == PixelFormat::NV12) ? 0 : 1);
1917 const size_t vbase = width * height + ((sourceOptions_.pixelFormat == PixelFormat::NV12) ? 1 : 0);
1918 IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA uvbase:(%{public}zu, %{public}zu),"
1919 "width:(%{public}zu, %{public}zu)", ubase, vbase, width, uvwidth);
1920
1921 for (size_t h = 0; h < height; h++) {
1922 const size_t yline = h * width;
1923 const size_t uvline = (h >> 1) * uvwidth;
1924
1925 for (size_t w = 0; w < width; w++) {
1926 const size_t ypos = yline + w;
1927 const size_t upos = ubase + uvline + (w & (~1));
1928 const size_t vpos = vbase + uvline + (w & (~1));
1929 const uint8_t y = (ypos < yuvSize) ? yuvPlane[ypos] : 0;
1930 const uint8_t u = (upos < yuvSize) ? yuvPlane[upos] : 0;
1931 const uint8_t v = (vpos < yuvSize) ? yuvPlane[vpos] : 0;
1932 // jpeg
1933 const uint8_t r = FloatToUint8((1.0f * y) + (1.402f * v) - (0.703749f * UINT8_MAX));
1934 const uint8_t g = FloatToUint8((1.0f * y) - (0.344136f * u) - (0.714136f * v) + (0.531211f * UINT8_MAX));
1935 const uint8_t b = FloatToUint8((1.0f * y) + (1.772f * u) - (0.889475f * UINT8_MAX));
1936
1937 const size_t rgbpos = ypos << 2;
1938 if ((rgbpos + NUM_3) < size) {
1939 data[rgbpos + NUM_0] = r;
1940 data[rgbpos + NUM_1] = g;
1941 data[rgbpos + NUM_2] = b;
1942 data[rgbpos + NUM_3] = UINT8_MAX;
1943 }
1944 }
1945 }
1946 IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA OUT");
1947 return true;
1948 }
1949
CreatePixelMapForYUV(uint32_t & errorCode)1950 unique_ptr<PixelMap> ImageSource::CreatePixelMapForYUV(uint32_t &errorCode)
1951 {
1952 IMAGE_LOGD("[ImageSource]CreatePixelMapForYUV IN srcPixelFormat:%{public}d, srcSize:(%{public}d,"
1953 "%{public}d)", sourceOptions_.pixelFormat, sourceOptions_.size.width, sourceOptions_.size.height);
1954 DumpInputData("yuv");
1955
1956 unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
1957 if (pixelMap == nullptr) {
1958 IMAGE_LOGE("[ImageSource]create the pixel map unique_ptr fail.");
1959 errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
1960 return nullptr;
1961 }
1962
1963 ImageInfo info;
1964 info.baseDensity = sourceOptions_.baseDensity;
1965 info.size.width = sourceOptions_.size.width;
1966 info.size.height = sourceOptions_.size.height;
1967 info.pixelFormat = PixelFormat::RGBA_8888;
1968 info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
1969 errorCode = pixelMap->SetImageInfo(info);
1970 if (errorCode != SUCCESS) {
1971 IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
1972 return nullptr;
1973 }
1974
1975 size_t bufferSize = static_cast<size_t>(pixelMap->GetWidth() * pixelMap->GetHeight() * pixelMap->GetPixelBytes());
1976 auto buffer = malloc(bufferSize);
1977 if (buffer == nullptr) {
1978 IMAGE_LOGE("allocate memory size %{public}zu fail", bufferSize);
1979 errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
1980 return nullptr;
1981 }
1982
1983 pixelMap->SetEditable(false);
1984 pixelMap->SetPixelsAddr(buffer, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
1985
1986 if (!ConvertYUV420ToRGBA(static_cast<uint8_t *>(buffer), bufferSize, false, false, errorCode)) {
1987 IMAGE_LOGE("convert yuv420 to rgba issue, errorCode=%{public}u", errorCode);
1988 errorCode = ERROR;
1989 return nullptr;
1990 }
1991
1992 IMAGE_LOGD("[ImageSource]CreatePixelMapForYUV OUT");
1993 return pixelMap;
1994 }
1995
IsASTC(const uint8_t * fileData,size_t fileSize)1996 bool ImageSource::IsASTC(const uint8_t *fileData, size_t fileSize)
1997 {
1998 if (fileData == nullptr || fileSize < ASTC_HEADER_SIZE) {
1999 IMAGE_LOGE("[ImageSource]IsASTC fileData incorrect.");
2000 return false;
2001 }
2002 unsigned int magicVal = static_cast<unsigned int>(fileData[0]) + (static_cast<unsigned int>(fileData[1]) << 8) +
2003 (static_cast<unsigned int>(fileData[2]) << 16) + (static_cast<unsigned int>(fileData[3]) << 24);
2004 return magicVal == ASTC_MAGIC_ID;
2005 }
2006
GetImageInfoForASTC(ImageInfo & imageInfo)2007 bool ImageSource::GetImageInfoForASTC(ImageInfo& imageInfo)
2008 {
2009 ASTCInfo astcInfo;
2010 if (!GetASTCInfo(sourceStreamPtr_->GetDataPtr(), sourceStreamPtr_->GetStreamSize(), astcInfo)) {
2011 IMAGE_LOGE("[ImageSource] get astc image info failed.");
2012 return false;
2013 }
2014 imageInfo.size = astcInfo.size;
2015 switch (astcInfo.blockFootprint.width) {
2016 case NUM_4: {
2017 imageInfo.pixelFormat = PixelFormat::ASTC_4x4;
2018 break;
2019 }
2020 case NUM_6: {
2021 imageInfo.pixelFormat = PixelFormat::ASTC_6x6;
2022 break;
2023 }
2024 case NUM_8: {
2025 imageInfo.pixelFormat = PixelFormat::ASTC_8x8;
2026 break;
2027 }
2028 default:
2029 IMAGE_LOGE("[ImageSource]GetImageInfoForASTC pixelFormat is unknown.");
2030 imageInfo.pixelFormat = PixelFormat::UNKNOWN;
2031 }
2032 return true;
2033 }
2034
CreatePixelMapForASTC(uint32_t & errorCode)2035 unique_ptr<PixelMap> ImageSource::CreatePixelMapForASTC(uint32_t &errorCode)
2036 #if defined(A_PLATFORM) || defined(IOS_PLATFORM)
2037 {
2038 errorCode = ERROR;
2039 return nullptr;
2040 }
2041 #else
2042 {
2043 ImageTrace imageTrace("CreatePixelMapForASTC");
2044 unique_ptr<PixelAstc> pixelAstc = make_unique<PixelAstc>();
2045
2046 ImageInfo info;
2047 if (!GetImageInfoForASTC(info)) {
2048 IMAGE_LOGE("[ImageSource] get astc image info failed.");
2049 return nullptr;
2050 }
2051 errorCode = pixelAstc->SetImageInfo(info);
2052 pixelAstc->SetAstcRealSize(info.size);
2053 if (errorCode != SUCCESS) {
2054 IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
2055 return nullptr;
2056 }
2057 pixelAstc->SetEditable(false);
2058 size_t fileSize = sourceStreamPtr_->GetStreamSize();
2059 int fd = AshmemCreate("CreatePixelMapForASTC Data", fileSize);
2060 if (fd < 0) {
2061 IMAGE_LOGE("[ImageSource]CreatePixelMapForASTC AshmemCreate fd < 0.");
2062 return nullptr;
2063 }
2064 int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
2065 if (result < 0) {
2066 IMAGE_LOGE("[ImageSource]CreatePixelMapForASTC AshmemSetPort error.");
2067 ::close(fd);
2068 return nullptr;
2069 }
2070 void* ptr = ::mmap(nullptr, fileSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
2071 if (ptr == MAP_FAILED || ptr == nullptr) {
2072 IMAGE_LOGE("[ImageSource]CreatePixelMapForASTC data is nullptr.");
2073 ::close(fd);
2074 return nullptr;
2075 }
2076 auto data = static_cast<uint8_t*>(ptr);
2077 void* fdPtr = new int32_t();
2078 *static_cast<int32_t*>(fdPtr) = fd;
2079 pixelAstc->SetPixelsAddr(data, fdPtr, fileSize, Media::AllocatorType::SHARE_MEM_ALLOC, nullptr);
2080 memcpy_s(data, fileSize, sourceStreamPtr_->GetDataPtr(), fileSize);
2081 pixelAstc->SetAstc(true);
2082 return pixelAstc;
2083 }
2084 #endif
2085
GetASTCInfo(const uint8_t * fileData,size_t fileSize,ASTCInfo & astcInfo)2086 bool ImageSource::GetASTCInfo(const uint8_t *fileData, size_t fileSize, ASTCInfo& astcInfo)
2087 {
2088 if (fileData == nullptr || fileSize < ASTC_HEADER_SIZE) {
2089 IMAGE_LOGE("[ImageSource]GetASTCInfo fileData incorrect.");
2090 return false;
2091 }
2092 astcInfo.size.width = static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_X]) +
2093 (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_X + 1]) << NUM_8) +
2094 (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_X + NUM_2]) << NUM_16);
2095 astcInfo.size.height = static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_Y]) +
2096 (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_Y + 1]) << NUM_8) +
2097 (static_cast<unsigned int>(fileData[ASTC_HEADER_DIM_Y + NUM_2]) << NUM_16);
2098 astcInfo.blockFootprint.width = fileData[ASTC_HEADER_BLOCK_X];
2099 astcInfo.blockFootprint.height = fileData[ASTC_HEADER_BLOCK_Y];
2100 return true;
2101 }
2102
CreatePixelMapList(const DecodeOptions & opts,uint32_t & errorCode)2103 unique_ptr<vector<unique_ptr<PixelMap>>> ImageSource::CreatePixelMapList(const DecodeOptions &opts,
2104 uint32_t &errorCode)
2105 {
2106 DumpInputData();
2107 auto frameCount = GetFrameCount(errorCode);
2108 if (errorCode != SUCCESS) {
2109 IMAGE_LOGE("[ImageSource]CreatePixelMapList get frame count error.");
2110 return nullptr;
2111 }
2112
2113 auto pixelMaps = std::make_unique<vector<unique_ptr<PixelMap>>>();
2114 for (uint32_t index = 0; index < frameCount; index++) {
2115 auto pixelMap = CreatePixelMap(index, opts, errorCode);
2116 if (errorCode != SUCCESS) {
2117 IMAGE_LOGE("[ImageSource]CreatePixelMapList create PixelMap error. index=%{public}u", index);
2118 return nullptr;
2119 }
2120 pixelMaps->push_back(std::move(pixelMap));
2121 }
2122
2123 errorCode = SUCCESS;
2124
2125 return pixelMaps;
2126 }
2127
GetDelayTime(uint32_t & errorCode)2128 unique_ptr<vector<int32_t>> ImageSource::GetDelayTime(uint32_t &errorCode)
2129 {
2130 auto frameCount = GetFrameCount(errorCode);
2131 if (errorCode != SUCCESS) {
2132 IMAGE_LOGE("[ImageSource]GetDelayTime get frame sum error.");
2133 return nullptr;
2134 }
2135
2136 auto delayTimes = std::make_unique<vector<int32_t>>();
2137 const string GIF_IMAGE_DELAY_TIME = "GIFDelayTime";
2138 for (uint32_t index = 0; index < frameCount; index++) {
2139 string delayTimeStr;
2140 errorCode = mainDecoder_->GetImagePropertyString(index, GIF_IMAGE_DELAY_TIME, delayTimeStr);
2141 if (errorCode != SUCCESS) {
2142 IMAGE_LOGE("[ImageSource]GetDelayTime get delay time issue. index=%{public}u", index);
2143 return nullptr;
2144 }
2145 if (!IsNumericStr(delayTimeStr)) {
2146 IMAGE_LOGE("[ImageSource]GetDelayTime not a numeric string. delayTimeStr=%{public}s",
2147 delayTimeStr.c_str());
2148 return nullptr;
2149 }
2150 int delayTime = 0;
2151 if (!StrToInt(delayTimeStr, delayTime)) {
2152 IMAGE_LOGE("[ImageSource]GetDelayTime to int fail. delayTimeStr=%{public}s", delayTimeStr.c_str());
2153 return nullptr;
2154 }
2155 delayTimes->push_back(delayTime);
2156 }
2157
2158 errorCode = SUCCESS;
2159
2160 return delayTimes;
2161 }
2162
GetFrameCount(uint32_t & errorCode)2163 uint32_t ImageSource::GetFrameCount(uint32_t &errorCode)
2164 {
2165 uint32_t frameCount = GetSourceInfo(errorCode).topLevelImageNum;
2166 if (errorCode != SUCCESS) {
2167 IMAGE_LOGE("[ImageSource]GetFrameCount get source info error.");
2168 return 0;
2169 }
2170
2171 if (InitMainDecoder() != SUCCESS) {
2172 IMAGE_LOGE("[ImageSource]GetFrameCount image decode plugin is null.");
2173 errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
2174 return 0;
2175 }
2176
2177 return frameCount;
2178 }
2179
DumpInputData(const std::string & fileSuffix)2180 void ImageSource::DumpInputData(const std::string& fileSuffix)
2181 {
2182 if (!ImageSystemProperties::GetDumpImageEnabled()) {
2183 return;
2184 }
2185
2186 if (sourceStreamPtr_ == nullptr) {
2187 IMAGE_LOGI("ImageSource::DumpInputData failed, streamPtr is null");
2188 return;
2189 }
2190
2191 uint8_t* data = sourceStreamPtr_->GetDataPtr();
2192 size_t size = sourceStreamPtr_->GetStreamSize();
2193
2194 ImageUtils::DumpDataIfDumpEnabled(reinterpret_cast<const char*>(data), size, fileSuffix, imageId_);
2195 }
2196
2197 #ifdef IMAGE_PURGEABLE_PIXELMAP
GetSourceSize() const2198 size_t ImageSource::GetSourceSize() const
2199 {
2200 return sourceStreamPtr_ ? sourceStreamPtr_->GetStreamSize() : 0;
2201 }
2202 #endif
2203
IsSupportGenAstc()2204 bool ImageSource::IsSupportGenAstc()
2205 {
2206 return ImageSystemProperties::GetMediaLibraryAstcEnabled();
2207 }
2208 } // namespace Media
2209 } // namespace OHOS
2210