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