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