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