• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "image_source.h"
17 
18 #include <algorithm>
19 #include <vector>
20 #include "buffer_source_stream.h"
21 #if !defined(_WIN32) && !defined(_APPLE)
22 #include "hitrace_meter.h"
23 #endif
24 #include "file_source_stream.h"
25 #include "image/abs_image_decoder.h"
26 #include "image/abs_image_format_agent.h"
27 #include "image/image_plugin_type.h"
28 #include "image_log.h"
29 #include "image_utils.h"
30 #include "incremental_source_stream.h"
31 #include "istream_source_stream.h"
32 #include "media_errors.h"
33 #include "pixel_map.h"
34 #include "plugin_server.h"
35 #include "post_proc.h"
36 #include "source_stream.h"
37 #if defined(_ANDROID) || defined(_IOS)
38 #include "include/jpeg_decoder.h"
39 #endif
40 #include "include/utils/SkBase64.h"
41 #include "image_trace.h"
42 
43 namespace OHOS {
44 namespace Media {
45 using namespace OHOS::HiviewDFX;
46 using namespace std;
47 using namespace ImagePlugin;
48 using namespace MultimediaPlugin;
49 
50 static const map<PixelFormat, PlPixelFormat> PIXEL_FORMAT_MAP = {
51     { PixelFormat::UNKNOWN, PlPixelFormat::UNKNOWN },     { PixelFormat::ARGB_8888, PlPixelFormat::ARGB_8888 },
52     { PixelFormat::ALPHA_8, PlPixelFormat::ALPHA_8 },     { PixelFormat::RGB_565, PlPixelFormat::RGB_565 },
53     { PixelFormat::RGBA_F16, PlPixelFormat::RGBA_F16 },   { PixelFormat::RGBA_8888, PlPixelFormat::RGBA_8888 },
54     { PixelFormat::BGRA_8888, PlPixelFormat::BGRA_8888 }, { PixelFormat::RGB_888, PlPixelFormat::RGB_888 },
55     { PixelFormat::NV21, PlPixelFormat::NV21 },           { PixelFormat::NV12, PlPixelFormat::NV12 },
56     { PixelFormat::CMYK, PlPixelFormat::CMYK }
57 };
58 
59 static const map<ColorSpace, PlColorSpace> COLOR_SPACE_MAP = {
60     { ColorSpace::UNKNOWN, PlColorSpace::UNKNOWN },
61     { ColorSpace::DISPLAY_P3, PlColorSpace::DISPLAY_P3 },
62     { ColorSpace::SRGB, PlColorSpace::SRGB },
63     { ColorSpace::LINEAR_SRGB, PlColorSpace::LINEAR_SRGB },
64     { ColorSpace::EXTENDED_SRGB, PlColorSpace::EXTENDED_SRGB },
65     { ColorSpace::LINEAR_EXTENDED_SRGB, PlColorSpace::LINEAR_EXTENDED_SRGB },
66     { ColorSpace::GENERIC_XYZ, PlColorSpace::GENERIC_XYZ },
67     { ColorSpace::GENERIC_LAB, PlColorSpace::GENERIC_LAB },
68     { ColorSpace::ACES, PlColorSpace::ACES },
69     { ColorSpace::ACES_CG, PlColorSpace::ACES_CG },
70     { ColorSpace::ADOBE_RGB_1998, PlColorSpace::ADOBE_RGB_1998 },
71     { ColorSpace::DCI_P3, PlColorSpace::DCI_P3 },
72     { ColorSpace::ITU_709, PlColorSpace::ITU_709 },
73     { ColorSpace::ITU_2020, PlColorSpace::ITU_2020 },
74     { ColorSpace::ROMM_RGB, PlColorSpace::ROMM_RGB },
75     { ColorSpace::NTSC_1953, PlColorSpace::NTSC_1953 },
76     { ColorSpace::SMPTE_C, PlColorSpace::SMPTE_C }
77 };
78 
79 namespace InnerFormat {
80     const string RAW_FORMAT = "image/x-raw";
81     const string EXTENDED_FORMAT = "image/x-skia";
82     const string RAW_EXTENDED_FORMATS[] = {
83         "image/x-sony-arw",
84         "image/x-canon-cr2",
85         "image/x-adobe-dng",
86         "image/x-nikon-nef",
87         "image/x-nikon-nrw",
88         "image/x-olympus-orf",
89         "image/x-fuji-raf",
90         "image/x-panasonic-rw2",
91         "image/x-pentax-pef",
92         "image/x-samsung-srw",
93     };
94 } // namespace InnerFormat
95 // BASE64 image prefix type data:image/<type>;base64,<data>
96 static const std::string IMAGE_URL_PREFIX = "data:image/";
97 static const std::string BASE64_URL_PREFIX = ";base64,";
98 static const int INT_2 = 2;
99 static const int INT_8 = 8;
100 static const uint8_t NUM_0 = 0;
101 static const uint8_t NUM_1 = 1;
102 static const uint8_t NUM_2 = 2;
103 static const uint8_t NUM_3 = 3;
104 
105 PluginServer &ImageSource::pluginServer_ = ImageUtils::GetPluginServer();
106 ImageSource::FormatAgentMap ImageSource::formatAgentMap_ = InitClass();
107 
GetSupportedFormats(set<string> & formats)108 uint32_t ImageSource::GetSupportedFormats(set<string> &formats)
109 {
110     IMAGE_LOGD("[ImageSource]get supported image type.");
111 
112     formats.clear();
113     vector<ClassInfo> classInfos;
114     uint32_t ret = pluginServer_.PluginServerGetClassInfo<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT,
115                                                                            classInfos);
116     if (ret != SUCCESS) {
117         IMAGE_LOGE("[ImageSource]get class info from plugin server,ret:%{public}u.", ret);
118         return ret;
119     }
120 
121     for (auto &info : classInfos) {
122         map<string, AttrData> &capbility = info.capabilities;
123         auto iter = capbility.find(IMAGE_ENCODE_FORMAT);
124         if (iter == capbility.end()) {
125             continue;
126         }
127 
128         AttrData &attr = iter->second;
129         const string *format = nullptr;
130         if (attr.GetValue(format) != SUCCESS) {
131             IMAGE_LOGE("[ImageSource]attr data get format failed.");
132             continue;
133         }
134 
135         if (*format == InnerFormat::RAW_FORMAT) {
136             formats.insert(std::begin(InnerFormat::RAW_EXTENDED_FORMATS), std::end(InnerFormat::RAW_EXTENDED_FORMATS));
137         } else {
138             formats.insert(*format);
139         }
140     }
141     return SUCCESS;
142 }
143 
CreateImageSource(unique_ptr<istream> is,const SourceOptions & opts,uint32_t & errorCode)144 unique_ptr<ImageSource> ImageSource::CreateImageSource(unique_ptr<istream> is, const SourceOptions &opts,
145                                                        uint32_t &errorCode)
146 {
147 #if !defined(_WIN32) && !defined(_APPLE)
148     StartTrace(HITRACE_TAG_ZIMAGE, "CreateImageSource by istream");
149 #endif
150     IMAGE_LOGD("[ImageSource]create Imagesource with stream.");
151 
152     unique_ptr<SourceStream> streamPtr = IstreamSourceStream::CreateSourceStream(move(is));
153     if (streamPtr == nullptr) {
154         IMAGE_LOGE("[ImageSource]failed to create istream source stream.");
155         errorCode = ERR_IMAGE_SOURCE_DATA;
156         return nullptr;
157     }
158 
159     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
160     if (sourcePtr == nullptr) {
161         IMAGE_LOGE("[ImageSource]failed to create ImageSource with stream.");
162         errorCode = ERR_IMAGE_SOURCE_DATA;
163         return nullptr;
164     }
165     errorCode = SUCCESS;
166 #if !defined(_WIN32) && !defined(_APPLE)
167     FinishTrace(HITRACE_TAG_ZIMAGE);
168 #endif
169     return unique_ptr<ImageSource>(sourcePtr);
170 }
171 
CreateImageSource(const uint8_t * data,uint32_t size,const SourceOptions & opts,uint32_t & errorCode)172 unique_ptr<ImageSource> ImageSource::CreateImageSource(const uint8_t *data, uint32_t size, const SourceOptions &opts,
173                                                        uint32_t &errorCode)
174 {
175 #if !defined(_WIN32) && !defined(_APPLE)
176     StartTrace(HITRACE_TAG_ZIMAGE, "CreateImageSource by data");
177 #endif
178     IMAGE_LOGD("[ImageSource]create Imagesource with buffer.");
179 
180     if (data == nullptr || size == 0) {
181         IMAGE_LOGE("[ImageSource]parameter error.");
182         errorCode = ERR_IMAGE_DATA_ABNORMAL;
183         return nullptr;
184     }
185 
186     unique_ptr<SourceStream> streamPtr = DecodeBase64(data, size);
187     if (streamPtr == nullptr) {
188         streamPtr = BufferSourceStream::CreateSourceStream(data, size);
189     }
190 
191     if (streamPtr == nullptr) {
192         IMAGE_LOGE("[ImageSource]failed to create buffer source stream.");
193         errorCode = ERR_IMAGE_SOURCE_DATA;
194         return nullptr;
195     }
196 
197     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
198     if (sourcePtr == nullptr) {
199         IMAGE_LOGE("[ImageSource]failed to create ImageSource with buffer.");
200         errorCode = ERR_IMAGE_SOURCE_DATA;
201         return nullptr;
202     }
203     errorCode = SUCCESS;
204 #if !defined(_WIN32) && !defined(_APPLE)
205     FinishTrace(HITRACE_TAG_ZIMAGE);
206 #endif
207     return unique_ptr<ImageSource>(sourcePtr);
208 }
209 
CreateImageSource(const std::string & pathName,const SourceOptions & opts,uint32_t & errorCode)210 unique_ptr<ImageSource> ImageSource::CreateImageSource(const std::string &pathName, const SourceOptions &opts,
211                                                        uint32_t &errorCode)
212 {
213 #if !defined(_WIN32) && !defined(_APPLE)
214     StartTrace(HITRACE_TAG_ZIMAGE, "CreateImageSource by path");
215 #endif
216     IMAGE_LOGD("[ImageSource]create Imagesource with pathName.");
217 
218     unique_ptr<SourceStream> streamPtr = DecodeBase64(pathName);
219     if (streamPtr == nullptr) {
220         streamPtr = FileSourceStream::CreateSourceStream(pathName);
221     }
222 
223     if (streamPtr == nullptr) {
224         IMAGE_LOGE("[ImageSource]failed to create file source stream.");
225         errorCode = ERR_IMAGE_SOURCE_DATA;
226         return nullptr;
227     }
228 
229     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
230     if (sourcePtr == nullptr) {
231         IMAGE_LOGE("[ImageSource]failed to create ImageSource with pathName.");
232         errorCode = ERR_IMAGE_SOURCE_DATA;
233         return nullptr;
234     }
235     errorCode = SUCCESS;
236 #if !defined(_WIN32) && !defined(_APPLE)
237     FinishTrace(HITRACE_TAG_ZIMAGE);
238 #endif
239     return unique_ptr<ImageSource>(sourcePtr);
240 }
241 
CreateImageSource(const int fd,const SourceOptions & opts,uint32_t & errorCode)242 unique_ptr<ImageSource> ImageSource::CreateImageSource(const int fd, const SourceOptions &opts,
243                                                        uint32_t &errorCode)
244 {
245 #if !defined(_WIN32) && !defined(_APPLE)
246     StartTrace(HITRACE_TAG_ZIMAGE, "CreateImageSource by fd");
247 #endif
248     unique_ptr<SourceStream> streamPtr = FileSourceStream::CreateSourceStream(fd);
249     if (streamPtr == nullptr) {
250         IMAGE_LOGE("[ImageSource]failed to create file source stream.");
251         errorCode = ERR_IMAGE_SOURCE_DATA;
252         return nullptr;
253     }
254     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
255     if (sourcePtr == nullptr) {
256         IMAGE_LOGE("[ImageSource]failed to create ImageSource by fd.");
257         errorCode = ERR_IMAGE_SOURCE_DATA;
258         return nullptr;
259     }
260     errorCode = SUCCESS;
261 #if !defined(_WIN32) && !defined(_APPLE)
262     FinishTrace(HITRACE_TAG_ZIMAGE);
263 #endif
264     return unique_ptr<ImageSource>(sourcePtr);
265 }
CreateIncrementalImageSource(const IncrementalSourceOptions & opts,uint32_t & errorCode)266 unique_ptr<ImageSource> ImageSource::CreateIncrementalImageSource(const IncrementalSourceOptions &opts,
267                                                                   uint32_t &errorCode)
268 {
269     IMAGE_LOGD("[ImageSource]create incremental ImageSource.");
270 
271     unique_ptr<SourceStream> streamPtr = IncrementalSourceStream::CreateSourceStream(opts.incrementalMode);
272     if (streamPtr == nullptr) {
273         IMAGE_LOGE("[ImageSource]failed to create incremental source stream.");
274         errorCode = ERR_IMAGE_SOURCE_DATA;
275         return nullptr;
276     }
277 
278     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts.sourceOptions);
279     if (sourcePtr == nullptr) {
280         IMAGE_LOGE("[ImageSource]failed to create incremental ImageSource.");
281         errorCode = ERR_IMAGE_SOURCE_DATA;
282         return nullptr;
283     }
284     sourcePtr->SetIncrementalSource(true);
285     errorCode = SUCCESS;
286     return unique_ptr<ImageSource>(sourcePtr);
287 }
288 
Reset()289 void ImageSource::Reset()
290 {
291     // if use skia now, no need reset
292     if (mainDecoder_ != nullptr && mainDecoder_->HasProperty(SKIA_DECODER)) {
293         return;
294     }
295     imageStatusMap_.clear();
296     decodeState_ = SourceDecodingState::UNRESOLVED;
297     sourceStreamPtr_->Seek(0);
298     mainDecoder_ = nullptr;
299 }
300 
CreatePixelMapEx(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)301 unique_ptr<PixelMap> ImageSource::CreatePixelMapEx(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
302 {
303     IMAGE_LOGD("[ImageSource]CreatePixelMapEx srcPixelFormat:%{public}d, srcSize:(%{public}d, %{public}d)",
304         sourceOptions_.pixelFormat, sourceOptions_.size.width, sourceOptions_.size.height);
305 
306     if (IsSpecialYUV()) {
307         return CreatePixelMapForYUV(errorCode);
308     }
309 
310     return CreatePixelMap(index, opts, errorCode);
311 }
312 
CreatePixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)313 unique_ptr<PixelMap> ImageSource::CreatePixelMap(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
314 {
315 #if !defined(_WIN32) && !defined(_APPLE)
316     StartTrace(HITRACE_TAG_ZIMAGE, "CreatePixelMap");
317 #endif
318     std::unique_lock<std::mutex> guard(decodingMutex_);
319     opts_ = opts;
320     bool useSkia = opts_.sampleSize != 1;
321     if (useSkia) {
322         // we need reset to initial state to choose correct decoder
323         Reset();
324     }
325     auto iter = GetValidImageStatus(index, errorCode);
326     if (iter == imageStatusMap_.end()) {
327         IMAGE_LOGE("[ImageSource]get valid image status fail on create pixel map, ret:%{public}u.", errorCode);
328         return nullptr;
329     }
330     // the mainDecoder_ may be borrowed by Incremental decoding, so needs to be checked.
331     if (InitMainDecoder() != SUCCESS) {
332         IMAGE_LOGE("[ImageSource]image decode plugin is null.");
333         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
334         return nullptr;
335     }
336     unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
337     if (pixelMap == nullptr || pixelMap.get() == nullptr) {
338         IMAGE_LOGE("[ImageSource]create the pixel map unique_ptr fail.");
339         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
340         return nullptr;
341     }
342 
343     ImagePlugin::PlImageInfo plInfo;
344     errorCode = SetDecodeOptions(mainDecoder_, index, opts_, plInfo);
345     if (errorCode != SUCCESS) {
346         IMAGE_LOGE("[ImageSource]set decode options error (index:%{public}u), ret:%{public}u.", index, errorCode);
347         return nullptr;
348     }
349 
350     for (auto listener : decodeListeners_) {
351         guard.unlock();
352         listener->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
353         guard.lock();
354     }
355 
356     Size size = {
357         .width = plInfo.size.width,
358         .height = plInfo.size.height
359     };
360     PostProc::ValidCropValue(opts_.CropRect, size);
361     errorCode = UpdatePixelMapInfo(opts_, plInfo, *(pixelMap.get()));
362     if (errorCode != SUCCESS) {
363         IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
364         return nullptr;
365     }
366 
367     DecodeContext context;
368     FinalOutputStep finalOutputStep = FinalOutputStep::NO_CHANGE;
369     if (!useSkia) {
370         bool hasNinePatch = mainDecoder_->HasProperty(NINE_PATCH);
371         finalOutputStep = GetFinalOutputStep(opts_, *(pixelMap.get()), hasNinePatch);
372         IMAGE_LOGD("[ImageSource]finalOutputStep:%{public}d. opts.allocatorType %{public}d",
373             finalOutputStep, opts_.allocatorType);
374 
375         if (finalOutputStep == FinalOutputStep::NO_CHANGE) {
376             context.allocatorType = opts_.allocatorType;
377         } else {
378             context.allocatorType = AllocatorType::HEAP_ALLOC;
379         }
380     }
381 
382     errorCode = mainDecoder_->Decode(index, context);
383     if (context.ifPartialOutput) {
384         for (auto partialListener : decodeListeners_) {
385             guard.unlock();
386             partialListener->OnEvent((int)DecodeEvent::EVENT_PARTIAL_DECODE);
387             guard.lock();
388         }
389     }
390     if (!useSkia) {
391         ninePatchInfo_.ninePatch = context.ninePatchContext.ninePatch;
392         ninePatchInfo_.patchSize = context.ninePatchContext.patchSize;
393     }
394     guard.unlock();
395     if (errorCode != SUCCESS) {
396         IMAGE_LOGE("[ImageSource]decode source fail, ret:%{public}u.", errorCode);
397         if (context.pixelsBuffer.buffer != nullptr) {
398             if (context.freeFunc != nullptr) {
399                 context.freeFunc(context.pixelsBuffer.buffer, context.pixelsBuffer.context,
400                                  context.pixelsBuffer.bufferSize);
401             } else {
402                 free(context.pixelsBuffer.buffer);
403                 context.pixelsBuffer.buffer = nullptr;
404             }
405         }
406         return nullptr;
407     }
408 
409 #ifdef IMAGE_COLORSPACE_FLAG
410     // add graphic colorspace object to pixelMap.
411     bool isSupportICCProfile = mainDecoder_->IsSupportICCProfile();
412     if (isSupportICCProfile) {
413         OHOS::ColorManager::ColorSpace grColorSpace = mainDecoder_->getGrColorSpace();
414         pixelMap->InnerSetColorSpace(grColorSpace);
415     }
416 #endif
417 
418     pixelMap->SetPixelsAddr(context.pixelsBuffer.buffer, context.pixelsBuffer.context, context.pixelsBuffer.bufferSize,
419                             context.allocatorType, context.freeFunc);
420     DecodeOptions procOpts;
421     CopyOptionsToProcOpts(opts_, procOpts, *(pixelMap.get()));
422     PostProc postProc;
423     errorCode = postProc.DecodePostProc(procOpts, *(pixelMap.get()), finalOutputStep);
424     if (errorCode != SUCCESS) {
425         return nullptr;
426     }
427 
428     if (!context.ifPartialOutput) {
429         for (auto listener : decodeListeners_) {
430             listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
431         }
432     }
433 #if !defined(_WIN32) && !defined(_APPLE)
434     FinishTrace(HITRACE_TAG_ZIMAGE);
435 #endif
436     return pixelMap;
437 }
438 
CreateIncrementalPixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)439 unique_ptr<IncrementalPixelMap> ImageSource::CreateIncrementalPixelMap(uint32_t index, const DecodeOptions &opts,
440                                                                        uint32_t &errorCode)
441 {
442     IncrementalPixelMap *incPixelMapPtr = new (std::nothrow) IncrementalPixelMap(index, opts, this);
443     if (incPixelMapPtr == nullptr) {
444         IMAGE_LOGE("[ImageSource]create the incremental pixel map unique_ptr fail.");
445         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
446         return nullptr;
447     }
448     errorCode = SUCCESS;
449     return unique_ptr<IncrementalPixelMap>(incPixelMapPtr);
450 }
451 
PromoteDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,ImageDecodingState & state,uint8_t & decodeProgress)452 uint32_t ImageSource::PromoteDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
453                                       ImageDecodingState &state, uint8_t &decodeProgress)
454 {
455     state = ImageDecodingState::UNRESOLVED;
456     decodeProgress = 0;
457     uint32_t ret = SUCCESS;
458     std::unique_lock<std::mutex> guard(decodingMutex_);
459     opts_ = opts;
460     auto imageStatusIter = GetValidImageStatus(index, ret);
461     if (imageStatusIter == imageStatusMap_.end()) {
462         IMAGE_LOGE("[ImageSource]get valid image status fail on promote decoding, ret:%{public}u.", ret);
463         return ret;
464     }
465     auto incrementalRecordIter = incDecodingMap_.find(&pixelMap);
466     if (incrementalRecordIter == incDecodingMap_.end()) {
467         ret = AddIncrementalContext(pixelMap, incrementalRecordIter);
468         if (ret != SUCCESS) {
469             IMAGE_LOGE("[ImageSource]failed to add context on incremental decoding, ret:%{public}u.", ret);
470             return ret;
471         }
472     }
473     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::BASE_INFO_PARSED) {
474         IMAGE_LOGD("[ImageSource]promote decode : set decode options.");
475         ImagePlugin::PlImageInfo plInfo;
476         ret = SetDecodeOptions(incrementalRecordIter->second.decoder, index, opts_, plInfo);
477         if (ret != SUCCESS) {
478             IMAGE_LOGE("[ImageSource]set decode options error (image index:%{public}u), ret:%{public}u.", index, ret);
479             return ret;
480         }
481 
482         auto iterator = decodeEventMap_.find((int)DecodeEvent::EVENT_HEADER_DECODE);
483         if (iterator == decodeEventMap_.end()) {
484             decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_HEADER_DECODE, 1));
485             for (auto callback : decodeListeners_) {
486                 guard.unlock();
487                 callback->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
488                 guard.lock();
489             }
490         }
491         Size size = {
492             .width = plInfo.size.width,
493             .height = plInfo.size.height
494         };
495         PostProc::ValidCropValue(opts_.CropRect, size);
496         ret = UpdatePixelMapInfo(opts_, plInfo, pixelMap);
497         if (ret != SUCCESS) {
498             IMAGE_LOGE("[ImageSource]update pixelmap info error (image index:%{public}u), ret:%{public}u.", index, ret);
499             return ret;
500         }
501         incrementalRecordIter->second.IncrementalState = ImageDecodingState::IMAGE_DECODING;
502     }
503     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_DECODING) {
504         ret = DoIncrementalDecoding(index, opts_, pixelMap, incrementalRecordIter->second);
505         decodeProgress = incrementalRecordIter->second.decodingProgress;
506         state = incrementalRecordIter->second.IncrementalState;
507         if (isIncrementalCompleted_) {
508             PostProc postProc;
509             ret = postProc.DecodePostProc(opts_, pixelMap);
510             if (state == ImageDecodingState::IMAGE_DECODED) {
511                 auto iter = decodeEventMap_.find((int)DecodeEvent::EVENT_COMPLETE_DECODE);
512                 if (iter == decodeEventMap_.end()) {
513                     decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_COMPLETE_DECODE, 1));
514                     for (auto listener : decodeListeners_) {
515                         guard.unlock();
516                         listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
517                         guard.lock();
518                     }
519                 }
520             }
521         }
522         return ret;
523     }
524 
525     // IMAGE_ERROR or IMAGE_DECODED.
526     state = incrementalRecordIter->second.IncrementalState;
527     decodeProgress = incrementalRecordIter->second.decodingProgress;
528     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_ERROR) {
529         IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on incremental decoding.",
530                    incrementalRecordIter->second.IncrementalState);
531         return ERR_IMAGE_DECODE_ABNORMAL;
532     }
533     return SUCCESS;
534 }
535 
DetachIncrementalDecoding(PixelMap & pixelMap)536 void ImageSource::DetachIncrementalDecoding(PixelMap &pixelMap)
537 {
538     std::lock_guard<std::mutex> guard(decodingMutex_);
539     auto iter = incDecodingMap_.find(&pixelMap);
540     if (iter == incDecodingMap_.end()) {
541         return;
542     }
543 
544     if (mainDecoder_ == nullptr) {
545         // return back the decoder to mainDecoder_.
546         mainDecoder_ = std::move(iter->second.decoder);
547         iter->second.decoder = nullptr;
548     }
549     incDecodingMap_.erase(iter);
550 }
551 
UpdateData(const uint8_t * data,uint32_t size,bool isCompleted)552 uint32_t ImageSource::UpdateData(const uint8_t *data, uint32_t size, bool isCompleted)
553 {
554     if (sourceStreamPtr_ == nullptr) {
555         IMAGE_LOGE("[ImageSource]image source update data, source stream is null.");
556         return ERR_IMAGE_INVALID_PARAMETER;
557     }
558     std::lock_guard<std::mutex> guard(decodingMutex_);
559     if (isCompleted) {
560         isIncrementalCompleted_ = isCompleted;
561     }
562     return sourceStreamPtr_->UpdateData(data, size, isCompleted);
563 }
564 
GetDecodeEvent()565 DecodeEvent ImageSource::GetDecodeEvent()
566 {
567     return decodeEvent_;
568 }
569 
GetImageInfo(uint32_t index,ImageInfo & imageInfo)570 uint32_t ImageSource::GetImageInfo(uint32_t index, ImageInfo &imageInfo)
571 {
572 #if !defined(_WIN32) && !defined(_APPLE)
573     StartTrace(HITRACE_TAG_ZIMAGE, "GetImageInfo by index");
574 #endif
575     uint32_t ret = SUCCESS;
576     std::unique_lock<std::mutex> guard(decodingMutex_);
577     auto iter = GetValidImageStatus(index, ret);
578     if (iter == imageStatusMap_.end()) {
579         guard.unlock();
580         IMAGE_LOGE("[ImageSource]get valid image status fail on get image info, ret:%{public}u.", ret);
581         return ret;
582     }
583     ImageInfo &info = (iter->second).imageInfo;
584     if (info.size.width == 0 || info.size.height == 0) {
585         IMAGE_LOGE("[ImageSource]get the image size fail on get image info, width:%{public}d, height:%{public}d.",
586                    info.size.width, info.size.height);
587         return ERR_IMAGE_DECODE_FAILED;
588     }
589 
590     imageInfo = info;
591 #if !defined(_WIN32) && !defined(_APPLE)
592     FinishTrace(HITRACE_TAG_ZIMAGE);
593 #endif
594     return SUCCESS;
595 }
596 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,const std::string & path)597 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
598     const std::string &value, const std::string &path)
599 {
600     std::unique_lock<std::mutex> guard(decodingMutex_);
601     uint32_t ret;
602     auto iter = GetValidImageStatus(0, ret);
603     if (iter == imageStatusMap_.end()) {
604         IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
605         return ret;
606     }
607     ret = mainDecoder_->ModifyImageProperty(index, key, value, path);
608     if (ret != SUCCESS) {
609         IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
610         return ret;
611     }
612     return SUCCESS;
613 }
614 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,const int fd)615 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
616     const std::string &value, const int fd)
617 {
618     std::unique_lock<std::mutex> guard(decodingMutex_);
619     uint32_t ret;
620     auto iter = GetValidImageStatus(0, ret);
621     if (iter == imageStatusMap_.end()) {
622         IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
623         return ret;
624     }
625     ret = mainDecoder_->ModifyImageProperty(index, key, value, fd);
626     if (ret != SUCCESS) {
627         IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
628         return ret;
629     }
630     return SUCCESS;
631 }
632 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,uint8_t * data,uint32_t size)633 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
634     const std::string &value, uint8_t *data, uint32_t size)
635 {
636     std::unique_lock<std::mutex> guard(decodingMutex_);
637     uint32_t ret;
638     auto iter = GetValidImageStatus(0, ret);
639     if (iter == imageStatusMap_.end()) {
640         IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
641         return ret;
642     }
643     ret = mainDecoder_->ModifyImageProperty(index, key, value, data, size);
644     if (ret != SUCCESS) {
645         IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
646         return ret;
647     }
648     return SUCCESS;
649 }
650 
GetImagePropertyInt(uint32_t index,const std::string & key,int32_t & value)651 uint32_t ImageSource::GetImagePropertyInt(uint32_t index, const std::string &key, int32_t &value)
652 {
653     std::unique_lock<std::mutex> guard(decodingMutex_);
654     uint32_t ret;
655     auto iter = GetValidImageStatus(0, ret);
656     if (iter == imageStatusMap_.end()) {
657         IMAGE_LOGE("[ImageSource]get valid image status fail on get image property, ret:%{public}u.", ret);
658         return ret;
659     }
660 
661     ret = mainDecoder_->GetImagePropertyInt(index, key, value);
662     if (ret != SUCCESS) {
663         IMAGE_LOGE("[ImageSource] GetImagePropertyInt fail, ret:%{public}u", ret);
664         return ret;
665     }
666     return SUCCESS;
667 }
668 
GetImagePropertyString(uint32_t index,const std::string & key,std::string & value)669 uint32_t ImageSource::GetImagePropertyString(uint32_t index, const std::string &key, std::string &value)
670 {
671     std::unique_lock<std::mutex> guard(decodingMutex_);
672     uint32_t ret;
673     auto iter = GetValidImageStatus(0, ret);
674     if (iter == imageStatusMap_.end()) {
675         IMAGE_LOGE("[ImageSource]get valid image status fail on get image property, ret:%{public}u.", ret);
676         return ret;
677     }
678     ret = mainDecoder_->GetImagePropertyString(index, key, value);
679     if (ret != SUCCESS) {
680         IMAGE_LOGE("[ImageSource] GetImagePropertyString fail, ret:%{public}u", ret);
681         return ret;
682     }
683     return SUCCESS;
684 }
GetSourceInfo(uint32_t & errorCode)685 const SourceInfo &ImageSource::GetSourceInfo(uint32_t &errorCode)
686 {
687     std::lock_guard<std::mutex> guard(decodingMutex_);
688     if (IsSpecialYUV()) {
689         return sourceInfo_;
690     }
691     errorCode = DecodeSourceInfo(true);
692     return sourceInfo_;
693 }
694 
RegisterListener(PeerListener * listener)695 void ImageSource::RegisterListener(PeerListener *listener)
696 {
697     if (listener == nullptr) {
698         return;
699     }
700     std::lock_guard<std::mutex> guard(listenerMutex_);
701     listeners_.insert(listener);
702 }
703 
UnRegisterListener(PeerListener * listener)704 void ImageSource::UnRegisterListener(PeerListener *listener)
705 {
706     if (listener == nullptr) {
707         return;
708     }
709     std::lock_guard<std::mutex> guard(listenerMutex_);
710     auto iter = listeners_.find(listener);
711     if (iter != listeners_.end()) {
712         listeners_.erase(iter);
713     }
714 }
715 
AddDecodeListener(DecodeListener * listener)716 void ImageSource::AddDecodeListener(DecodeListener *listener)
717 {
718     if (listener == nullptr) {
719         IMAGE_LOGE("AddDecodeListener listener null");
720         return;
721     }
722     std::lock_guard<std::mutex> guard(listenerMutex_);
723     decodeListeners_.insert(listener);
724 }
725 
RemoveDecodeListener(DecodeListener * listener)726 void ImageSource::RemoveDecodeListener(DecodeListener *listener)
727 {
728     if (listener == nullptr) {
729         IMAGE_LOGE("RemoveDecodeListener listener null");
730         return;
731     }
732     std::lock_guard<std::mutex> guard(listenerMutex_);
733     auto iter = decodeListeners_.find(listener);
734     if (iter != decodeListeners_.end()) {
735         decodeListeners_.erase(iter);
736     }
737 }
738 
~ImageSource()739 ImageSource::~ImageSource()
740 {
741     std::lock_guard<std::mutex> guard(listenerMutex_);
742     for (const auto &listener : listeners_) {
743         listener->OnPeerDestory();
744     }
745 }
746 
IsStreamCompleted()747 bool ImageSource::IsStreamCompleted()
748 {
749     std::lock_guard<std::mutex> guard(decodingMutex_);
750     return sourceStreamPtr_->IsStreamCompleted();
751 }
752 
753 // ------------------------------- private method -------------------------------
ImageSource(unique_ptr<SourceStream> && stream,const SourceOptions & opts)754 ImageSource::ImageSource(unique_ptr<SourceStream> &&stream, const SourceOptions &opts)
755     : sourceStreamPtr_(stream.release())
756 {
757     sourceInfo_.encodedFormat = opts.formatHint;
758     sourceInfo_.baseDensity = opts.baseDensity;
759     sourceOptions_.formatHint = opts.formatHint;
760     sourceOptions_.baseDensity = opts.baseDensity;
761     sourceOptions_.pixelFormat = opts.pixelFormat;
762     sourceOptions_.size.width = opts.size.width;
763     sourceOptions_.size.height = opts.size.height;
764 }
765 
InitClass()766 ImageSource::FormatAgentMap ImageSource::InitClass()
767 {
768     vector<ClassInfo> classInfos;
769     pluginServer_.PluginServerGetClassInfo<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, classInfos);
770     set<string> formats;
771     for (auto &info : classInfos) {
772         auto &capabilities = info.capabilities;
773         auto iter = capabilities.find(IMAGE_ENCODE_FORMAT);
774         if (iter == capabilities.end()) {
775             continue;
776         }
777 
778         AttrData &attr = iter->second;
779         string format;
780         if (SUCCESS != attr.GetValue(format)) {
781             IMAGE_LOGE("[ImageSource]attr data get format:[%{public}s] failed.", format.c_str());
782             continue;
783         }
784         formats.insert(move(format));
785     }
786 
787     FormatAgentMap tempAgentMap;
788     AbsImageFormatAgent *formatAgent = nullptr;
789     for (auto format : formats) {
790         map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(format) } };
791         formatAgent =
792             pluginServer_.CreateObject<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, capabilities);
793         if (formatAgent == nullptr) {
794             continue;
795         }
796         tempAgentMap.insert(FormatAgentMap::value_type(std::move(format), formatAgent));
797     }
798     return tempAgentMap;
799 }
800 
CheckEncodedFormat(AbsImageFormatAgent & agent)801 uint32_t ImageSource::CheckEncodedFormat(AbsImageFormatAgent &agent)
802 {
803     uint32_t size = agent.GetHeaderSize();
804     ImagePlugin::DataStreamBuffer outData;
805     if (sourceStreamPtr_ == nullptr) {
806         IMAGE_LOGE("[ImageSource]check image format, source stream is null.");
807         return ERR_IMAGE_INVALID_PARAMETER;
808     }
809     if (!sourceStreamPtr_->Peek(size, outData)) {
810         IMAGE_LOGE("[ImageSource]stream peek the data fail.");
811         return ERR_IMAGE_SOURCE_DATA;
812     }
813 
814     if (outData.inputStreamBuffer == nullptr || outData.dataSize < size) {
815         IMAGE_LOGE("[ImageSource]the ouData is incomplete.");
816         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
817     }
818 
819     if (!agent.CheckFormat(outData.inputStreamBuffer, size)) {
820         IMAGE_LOGE("[ImageSource]check mismatched format :%{public}s.", agent.GetFormatType().c_str());
821         return ERR_IMAGE_MISMATCHED_FORMAT;
822     }
823     return SUCCESS;
824 }
825 
CheckFormatHint(const string & formatHint,FormatAgentMap::iterator & formatIter)826 uint32_t ImageSource::CheckFormatHint(const string &formatHint, FormatAgentMap::iterator &formatIter)
827 {
828     uint32_t ret = ERROR;
829     formatIter = formatAgentMap_.find(formatHint);
830     if (formatIter == formatAgentMap_.end()) {
831         IMAGE_LOGE("[ImageSource]check input format fail.");
832         return ret;
833     }
834     AbsImageFormatAgent *agent = formatIter->second;
835     ret = CheckEncodedFormat(*agent);
836     if (ret != SUCCESS) {
837         if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
838             IMAGE_LOGE("[ImageSource]image source incomplete.");
839         }
840         return ret;
841     }
842     return SUCCESS;
843 }
844 
GetEncodedFormat(const string & formatHint,string & format)845 uint32_t ImageSource::GetEncodedFormat(const string &formatHint, string &format)
846 {
847     bool streamIncomplete = false;
848     auto hintIter = formatAgentMap_.end();
849     if (!formatHint.empty()) {
850         uint32_t ret = CheckFormatHint(formatHint, hintIter);
851         if (ret == ERR_IMAGE_SOURCE_DATA) {
852             IMAGE_LOGE("[ImageSource]image source data error.");
853             return ret;
854         } else if (ret == SUCCESS) {
855             format = hintIter->first;
856             IMAGE_LOGD("[ImageSource]check input image format success, format:%{public}s.", format.c_str());
857             return SUCCESS;
858         } else if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
859             streamIncomplete = true;
860             IMAGE_LOGE("[ImageSource]image source data error ERR_IMAGE_SOURCE_DATA_INCOMPLETE.");
861         }
862     }
863 
864     for (auto iter = formatAgentMap_.begin(); iter != formatAgentMap_.end(); ++iter) {
865         string curFormat = iter->first;
866         if (iter == hintIter || curFormat == InnerFormat::RAW_FORMAT) {
867             continue;  // has been checked before.
868         }
869         AbsImageFormatAgent *agent = iter->second;
870         auto result = CheckEncodedFormat(*agent);
871         if (result == ERR_IMAGE_MISMATCHED_FORMAT) {
872             continue;
873         } else if (result == SUCCESS) {
874             IMAGE_LOGI("[ImageSource]GetEncodedFormat success format :%{public}s.", iter->first.c_str());
875             format = iter->first;
876             return SUCCESS;
877         } else if (result == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
878             streamIncomplete = true;
879         }
880     }
881 
882     if (streamIncomplete) {
883         IMAGE_LOGE("[ImageSource]image source incomplete.");
884         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
885     }
886 
887     // default return raw image
888     format = InnerFormat::RAW_FORMAT;
889     IMAGE_LOGI("[ImageSource]image default to raw format.");
890     return SUCCESS;
891 }
892 
OnSourceRecognized(bool isAcquiredImageNum)893 uint32_t ImageSource::OnSourceRecognized(bool isAcquiredImageNum)
894 {
895     uint32_t ret = InitMainDecoder();
896     if (ret != SUCCESS) {
897         sourceInfo_.state = SourceInfoState::UNSUPPORTED_FORMAT;
898         decodeState_ = SourceDecodingState::UNSUPPORTED_FORMAT;
899         IMAGE_LOGE("[ImageSource]image decode error, ret:[%{public}u].", ret);
900         return ret;
901     }
902 
903     // for raw image, we need check the original format after decoder initialzation
904     string value;
905     ret = mainDecoder_->GetImagePropertyString(0, ACTUAL_IMAGE_ENCODED_FORMAT, value);
906     if (ret == SUCCESS) {
907         // update new format
908         sourceInfo_.encodedFormat = value;
909         IMAGE_LOGI("[ImageSource] update new format, value:%{public}s", value.c_str());
910     } else {
911         IMAGE_LOGD("[ImageSource] GetImagePropertyString fail, ret:%{public}u", ret);
912     }
913 
914     if (isAcquiredImageNum) {
915         ret = mainDecoder_->GetTopLevelImageNum(sourceInfo_.topLevelImageNum);
916         if (ret != SUCCESS) {
917             if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
918                 sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
919                 IMAGE_LOGE("[ImageSource]image source data incomplete.");
920                 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
921             }
922             sourceInfo_.state = SourceInfoState::FILE_INFO_ERROR;
923             decodeState_ = SourceDecodingState::FILE_INFO_ERROR;
924             IMAGE_LOGE("[ImageSource]image source error.");
925             return ret;
926         }
927     }
928     sourceInfo_.state = SourceInfoState::FILE_INFO_PARSED;
929     decodeState_ = SourceDecodingState::FILE_INFO_DECODED;
930     return SUCCESS;
931 }
932 
OnSourceUnresolved()933 uint32_t ImageSource::OnSourceUnresolved()
934 {
935     string formatResult;
936     auto ret = GetEncodedFormat(sourceInfo_.encodedFormat, formatResult);
937     if (ret != SUCCESS) {
938         if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
939             IMAGE_LOGE("[ImageSource]image source incomplete.");
940             sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
941             return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
942         } else if (ret == ERR_IMAGE_UNKNOWN_FORMAT) {
943             IMAGE_LOGE("[ImageSource]image unknown format.");
944             sourceInfo_.state = SourceInfoState::UNKNOWN_FORMAT;
945             decodeState_ = SourceDecodingState::UNKNOWN_FORMAT;
946             return ERR_IMAGE_UNKNOWN_FORMAT;
947         }
948         sourceInfo_.state = SourceInfoState::SOURCE_ERROR;
949         decodeState_ = SourceDecodingState::SOURCE_ERROR;
950         IMAGE_LOGE("[ImageSource]image source error.");
951         return ret;
952     }
953     sourceInfo_.encodedFormat = formatResult;
954     decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
955     return SUCCESS;
956 }
957 
DecodeSourceInfo(bool isAcquiredImageNum)958 uint32_t ImageSource::DecodeSourceInfo(bool isAcquiredImageNum)
959 {
960     uint32_t ret = SUCCESS;
961     if (decodeState_ >= SourceDecodingState::FILE_INFO_DECODED) {
962         if (isAcquiredImageNum) {
963             decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
964         } else {
965             return SUCCESS;
966         }
967     }
968     if (decodeState_ == SourceDecodingState::UNRESOLVED) {
969         ret = OnSourceUnresolved();
970         if (ret != SUCCESS) {
971             IMAGE_LOGE("[ImageSource]unresolved source: check format failed, ret:[%{public}d].", ret);
972             return ret;
973         }
974     }
975     if (decodeState_ == SourceDecodingState::FORMAT_RECOGNIZED) {
976         ret = OnSourceRecognized(isAcquiredImageNum);
977         if (ret != SUCCESS) {
978             IMAGE_LOGE("[ImageSource]recognized source: get source info failed, ret:[%{public}d].", ret);
979             return ret;
980         }
981         return SUCCESS;
982     }
983     IMAGE_LOGE("[ImageSource]invalid source state %{public}d on decode source info.", decodeState_);
984     switch (decodeState_) {
985         case SourceDecodingState::SOURCE_ERROR: {
986             ret = ERR_IMAGE_SOURCE_DATA;
987             break;
988         }
989         case SourceDecodingState::UNKNOWN_FORMAT: {
990             ret = ERR_IMAGE_UNKNOWN_FORMAT;
991             break;
992         }
993         case SourceDecodingState::UNSUPPORTED_FORMAT: {
994             ret = ERR_IMAGE_PLUGIN_CREATE_FAILED;
995             break;
996         }
997         case SourceDecodingState::FILE_INFO_ERROR: {
998             ret = ERR_IMAGE_DECODE_FAILED;
999             break;
1000         }
1001         default: {
1002             ret = ERROR;
1003             break;
1004         }
1005     }
1006     return ret;
1007 }
1008 
DecodeImageInfo(uint32_t index,ImageStatusMap::iterator & iter)1009 uint32_t ImageSource::DecodeImageInfo(uint32_t index, ImageStatusMap::iterator &iter)
1010 {
1011     uint32_t ret = DecodeSourceInfo(false);
1012     if (ret != SUCCESS) {
1013         IMAGE_LOGE("[ImageSource]decode the image fail, ret:%{public}d.", ret);
1014         return ret;
1015     }
1016     if (mainDecoder_ == nullptr) {
1017         IMAGE_LOGE("[ImageSource]get image size, image decode plugin is null.");
1018         return ERR_IMAGE_PLUGIN_CREATE_FAILED;
1019     }
1020     ImagePlugin::PlSize size;
1021     ret = mainDecoder_->GetImageSize(index, size);
1022     if (ret == SUCCESS) {
1023         ImageDecodingStatus imageStatus;
1024         imageStatus.imageInfo.size.width = size.width;
1025         imageStatus.imageInfo.size.height = size.height;
1026         imageStatus.imageState = ImageDecodingState::BASE_INFO_PARSED;
1027         auto result = imageStatusMap_.insert(ImageStatusMap::value_type(index, imageStatus));
1028         iter = result.first;
1029         return SUCCESS;
1030     } else if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1031         IMAGE_LOGE("[ImageSource]source data incomplete.");
1032         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
1033     } else {
1034         ImageDecodingStatus status;
1035         status.imageState = ImageDecodingState::BASE_INFO_ERROR;
1036         auto errorResult = imageStatusMap_.insert(ImageStatusMap::value_type(index, status));
1037         iter = errorResult.first;
1038         IMAGE_LOGE("[ImageSource]decode the image info fail.");
1039         return ERR_IMAGE_DECODE_FAILED;
1040     }
1041 }
1042 
InitMainDecoder()1043 uint32_t ImageSource::InitMainDecoder()
1044 {
1045     if (mainDecoder_ != nullptr) {
1046         return SUCCESS;
1047     }
1048     uint32_t result = SUCCESS;
1049     mainDecoder_ = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(result));
1050     return result;
1051 }
1052 
CreateDecoder(uint32_t & errorCode)1053 AbsImageDecoder *ImageSource::CreateDecoder(uint32_t &errorCode)
1054 {
1055     // in normal mode, we can get actual encoded format to the user
1056     // but we need transfer to skia codec for adaption, "image/x-skia"
1057     std::string encodedFormat = sourceInfo_.encodedFormat;
1058     if (opts_.sampleSize != 1) {
1059         encodedFormat = InnerFormat::EXTENDED_FORMAT;
1060     }
1061 #if defined(_ANDROID) || defined(_IOS)
1062     auto decoder = new JpegDecoder();
1063 #else
1064     map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(encodedFormat) } };
1065     auto decoder = pluginServer_.CreateObject<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT, capabilities);
1066 #endif
1067     if (decoder == nullptr) {
1068         IMAGE_LOGE("[ImageSource]failed to create decoder object.");
1069         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
1070         return nullptr;
1071     }
1072     errorCode = SUCCESS;
1073     decoder->SetSource(*sourceStreamPtr_);
1074     return decoder;
1075 }
1076 
SetDecodeOptions(std::unique_ptr<AbsImageDecoder> & decoder,uint32_t index,const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo)1077 uint32_t ImageSource::SetDecodeOptions(std::unique_ptr<AbsImageDecoder> &decoder, uint32_t index,
1078                                        const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo)
1079 {
1080     PixelDecodeOptions plOptions;
1081     CopyOptionsToPlugin(opts, plOptions);
1082     uint32_t ret = decoder->SetDecodeOptions(index, plOptions, plInfo);
1083     if (ret != SUCCESS) {
1084         IMAGE_LOGE("[ImageSource]decoder plugin set decode options fail (image index:%{public}u), ret:%{public}u.",
1085                    index, ret);
1086         return ret;
1087     }
1088     auto iter = imageStatusMap_.find(index);
1089     if (iter != imageStatusMap_.end()) {
1090         ImageInfo &info = (iter->second).imageInfo;
1091         IMAGE_LOGD("[ImageSource]SetDecodeOptions plInfo.pixelFormat %{public}d", plInfo.pixelFormat);
1092 
1093         PlPixelFormat format = plInfo.pixelFormat;
1094         auto find_item = std::find_if(PIXEL_FORMAT_MAP.begin(), PIXEL_FORMAT_MAP.end(),
1095             [format](const std::map<PixelFormat, PlPixelFormat>::value_type item) {
1096             return item.second == format;
1097         });
1098         if (find_item != PIXEL_FORMAT_MAP.end()) {
1099             info.pixelFormat = (*find_item).first;
1100         }
1101         IMAGE_LOGD("[ImageSource]SetDecodeOptions info.pixelFormat %{public}d", info.pixelFormat);
1102     }
1103     return SUCCESS;
1104 }
1105 
UpdatePixelMapInfo(const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo,PixelMap & pixelMap)1106 uint32_t ImageSource::UpdatePixelMapInfo(const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo,
1107                                          PixelMap &pixelMap)
1108 {
1109     pixelMap.SetEditable(opts.editable);
1110 
1111     ImageInfo info;
1112     info.baseDensity = sourceInfo_.baseDensity;
1113     info.size.width = plInfo.size.width;
1114     info.size.height = plInfo.size.height;
1115     info.pixelFormat = static_cast<PixelFormat>(plInfo.pixelFormat);
1116     info.alphaType = static_cast<AlphaType>(plInfo.alphaType);
1117     return pixelMap.SetImageInfo(info);
1118 }
1119 
CopyOptionsToPlugin(const DecodeOptions & opts,PixelDecodeOptions & plOpts)1120 void ImageSource::CopyOptionsToPlugin(const DecodeOptions &opts, PixelDecodeOptions &plOpts)
1121 {
1122     plOpts.CropRect.left = opts.CropRect.left;
1123     plOpts.CropRect.top = opts.CropRect.top;
1124     plOpts.CropRect.width = opts.CropRect.width;
1125     plOpts.CropRect.height = opts.CropRect.height;
1126     plOpts.desiredSize.width = opts.desiredSize.width;
1127     plOpts.desiredSize.height = opts.desiredSize.height;
1128     plOpts.rotateDegrees = opts.rotateDegrees;
1129     plOpts.sampleSize = opts.sampleSize;
1130     auto formatSearch = PIXEL_FORMAT_MAP.find(opts.desiredPixelFormat);
1131     plOpts.desiredPixelFormat =
1132         (formatSearch != PIXEL_FORMAT_MAP.end()) ? formatSearch->second : PlPixelFormat::RGBA_8888;
1133     auto colorSearch = COLOR_SPACE_MAP.find(opts.desiredColorSpace);
1134     plOpts.desiredColorSpace = (colorSearch != COLOR_SPACE_MAP.end()) ? colorSearch->second : PlColorSpace::UNKNOWN;
1135     plOpts.allowPartialImage = opts.allowPartialImage;
1136     plOpts.editable = opts.editable;
1137 }
1138 
CopyOptionsToProcOpts(const DecodeOptions & opts,DecodeOptions & procOpts,PixelMap & pixelMap)1139 void ImageSource::CopyOptionsToProcOpts(const DecodeOptions &opts, DecodeOptions &procOpts, PixelMap &pixelMap)
1140 {
1141     procOpts.fitDensity = opts.fitDensity;
1142     procOpts.CropRect.left = opts.CropRect.left;
1143     procOpts.CropRect.top = opts.CropRect.top;
1144     procOpts.CropRect.width = opts.CropRect.width;
1145     procOpts.CropRect.height = opts.CropRect.height;
1146     procOpts.desiredSize.width = opts.desiredSize.width;
1147     procOpts.desiredSize.height = opts.desiredSize.height;
1148     procOpts.rotateDegrees = opts.rotateDegrees;
1149     procOpts.sampleSize = opts.sampleSize;
1150     procOpts.desiredPixelFormat = opts.desiredPixelFormat;
1151     if (opts.allocatorType == AllocatorType::DEFAULT) {
1152         procOpts.allocatorType = AllocatorType::HEAP_ALLOC;
1153     } else {
1154         procOpts.allocatorType = opts.allocatorType;
1155     }
1156     procOpts.desiredColorSpace = opts.desiredColorSpace;
1157     procOpts.allowPartialImage = opts.allowPartialImage;
1158     procOpts.editable = opts.editable;
1159     // we need preference_ when post processing
1160     procOpts.preference = preference_;
1161 }
1162 
GetValidImageStatus(uint32_t index,uint32_t & errorCode)1163 ImageSource::ImageStatusMap::iterator ImageSource::GetValidImageStatus(uint32_t index, uint32_t &errorCode)
1164 {
1165     auto iter = imageStatusMap_.find(index);
1166     if (iter == imageStatusMap_.end()) {
1167         errorCode = DecodeImageInfo(index, iter);
1168         if (errorCode != SUCCESS) {
1169             IMAGE_LOGE("[ImageSource]image info decode fail, ret:%{public}u.", errorCode);
1170             return imageStatusMap_.end();
1171         }
1172     } else if (iter->second.imageState < ImageDecodingState::BASE_INFO_PARSED) {
1173         IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on get image status.", iter->second.imageState);
1174         errorCode = ERR_IMAGE_DECODE_FAILED;
1175         return imageStatusMap_.end();
1176     }
1177     errorCode = SUCCESS;
1178     return iter;
1179 }
1180 
AddIncrementalContext(PixelMap & pixelMap,IncrementalRecordMap::iterator & iterator)1181 uint32_t ImageSource::AddIncrementalContext(PixelMap &pixelMap, IncrementalRecordMap::iterator &iterator)
1182 {
1183     uint32_t ret = SUCCESS;
1184     IncrementalDecodingContext context;
1185     if (mainDecoder_ != nullptr) {
1186         // borrowed decoder from the mainDecoder_.
1187         context.decoder = std::move(mainDecoder_);
1188     } else {
1189         context.decoder = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(ret));
1190     }
1191     if (context.decoder == nullptr) {
1192         IMAGE_LOGE("[ImageSource]failed to create decoder on add incremental context, ret:%{public}u.", ret);
1193         return ret;
1194     }
1195     // mainDecoder has parsed base info in DecodeImageInfo();
1196     context.IncrementalState = ImageDecodingState::BASE_INFO_PARSED;
1197     auto result = incDecodingMap_.insert(IncrementalRecordMap::value_type(&pixelMap, std::move(context)));
1198     iterator = result.first;
1199     return SUCCESS;
1200 }
1201 
DoIncrementalDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,IncrementalDecodingContext & recordContext)1202 uint32_t ImageSource::DoIncrementalDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
1203                                             IncrementalDecodingContext &recordContext)
1204 {
1205     IMAGE_LOGD("[ImageSource]do incremental decoding: begin.");
1206     uint8_t *pixelAddr = static_cast<uint8_t *>(pixelMap.GetWritablePixels());
1207     ProgDecodeContext context;
1208     context.decodeContext.pixelsBuffer.buffer = pixelAddr;
1209     uint32_t ret = recordContext.decoder->PromoteIncrementalDecode(index, context);
1210     if (context.decodeContext.pixelsBuffer.buffer != nullptr && pixelAddr == nullptr) {
1211         pixelMap.SetPixelsAddr(context.decodeContext.pixelsBuffer.buffer, context.decodeContext.pixelsBuffer.context,
1212                                context.decodeContext.pixelsBuffer.bufferSize, context.decodeContext.allocatorType,
1213                                context.decodeContext.freeFunc);
1214     }
1215     IMAGE_LOGD("[ImageSource]do incremental decoding progress:%{public}u.", context.totalProcessProgress);
1216     recordContext.decodingProgress = context.totalProcessProgress;
1217     if (ret != SUCCESS && ret != ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1218         recordContext.IncrementalState = ImageDecodingState::IMAGE_ERROR;
1219         IMAGE_LOGE("[ImageSource]do incremental decoding source fail, ret:%{public}u.", ret);
1220         return ret;
1221     }
1222     if (ret == SUCCESS) {
1223         recordContext.IncrementalState = ImageDecodingState::IMAGE_DECODED;
1224         IMAGE_LOGI("[ImageSource]do incremental decoding success.");
1225     }
1226     return ret;
1227 }
1228 
GetNinePatchInfo() const1229 const NinePatchInfo &ImageSource::GetNinePatchInfo() const
1230 {
1231     return ninePatchInfo_;
1232 }
1233 
SetMemoryUsagePreference(const MemoryUsagePreference preference)1234 void ImageSource::SetMemoryUsagePreference(const MemoryUsagePreference preference)
1235 {
1236     preference_ = preference;
1237 }
1238 
GetMemoryUsagePreference()1239 MemoryUsagePreference ImageSource::GetMemoryUsagePreference()
1240 {
1241     return preference_;
1242 }
1243 
GetFilterArea(const int & privacyType,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1244 uint32_t ImageSource::GetFilterArea(const int &privacyType, std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1245 {
1246     std::unique_lock<std::mutex> guard(decodingMutex_);
1247     uint32_t ret;
1248     auto iter = GetValidImageStatus(0, ret);
1249     if (iter == imageStatusMap_.end()) {
1250         IMAGE_LOGE("[ImageSource]get valid image status fail on get filter area, ret:%{public}u.", ret);
1251         return ret;
1252     }
1253     ret = mainDecoder_->GetFilterArea(privacyType, ranges);
1254     if (ret != SUCCESS) {
1255         IMAGE_LOGE("[ImageSource] GetFilterArea fail, ret:%{public}u", ret);
1256         return ret;
1257     }
1258     return SUCCESS;
1259 }
1260 
SetIncrementalSource(const bool isIncrementalSource)1261 void ImageSource::SetIncrementalSource(const bool isIncrementalSource)
1262 {
1263     isIncrementalSource_ = isIncrementalSource;
1264 }
1265 
IsIncrementalSource()1266 bool ImageSource::IsIncrementalSource()
1267 {
1268     return isIncrementalSource_;
1269 }
1270 
GetFinalOutputStep(const DecodeOptions & opts,PixelMap & pixelMap,bool hasNinePatch)1271 FinalOutputStep ImageSource::GetFinalOutputStep(const DecodeOptions &opts, PixelMap &pixelMap, bool hasNinePatch)
1272 {
1273     ImageInfo info;
1274     pixelMap.GetImageInfo(info);
1275     ImageInfo dstImageInfo;
1276     dstImageInfo.size = opts.desiredSize;
1277     dstImageInfo.pixelFormat = opts.desiredPixelFormat;
1278     if (opts.desiredPixelFormat == PixelFormat::UNKNOWN) {
1279         if (preference_ == MemoryUsagePreference::LOW_RAM && info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
1280             dstImageInfo.pixelFormat = PixelFormat::RGB_565;
1281         } else {
1282             dstImageInfo.pixelFormat = PixelFormat::RGBA_8888;
1283         }
1284     }
1285     // decode use, this value may be changed by real pixelFormat
1286     if (pixelMap.GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) {
1287         dstImageInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
1288     } else {
1289         dstImageInfo.alphaType = pixelMap.GetAlphaType();
1290     }
1291     bool densityChange = HasDensityChange(opts, info, hasNinePatch);
1292     bool sizeChange = ImageSizeChange(pixelMap.GetWidth(), pixelMap.GetHeight(),
1293                                       opts.desiredSize.width, opts.desiredSize.height);
1294     bool rotateChange = !ImageUtils::FloatCompareZero(opts.rotateDegrees);
1295     bool convertChange = ImageConverChange(opts.CropRect, dstImageInfo, info);
1296     if (sizeChange) {
1297         return FinalOutputStep::SIZE_CHANGE;
1298     }
1299     if (densityChange) {
1300         return FinalOutputStep::DENSITY_CHANGE;
1301     }
1302     if (rotateChange) {
1303         return FinalOutputStep::ROTATE_CHANGE;
1304     }
1305     if (convertChange) {
1306         return FinalOutputStep::CONVERT_CHANGE;
1307     }
1308     return FinalOutputStep::NO_CHANGE;
1309 }
1310 
HasDensityChange(const DecodeOptions & opts,ImageInfo & srcImageInfo,bool hasNinePatch)1311 bool ImageSource::HasDensityChange(const DecodeOptions &opts, ImageInfo &srcImageInfo, bool hasNinePatch)
1312 {
1313     return !hasNinePatch && (srcImageInfo.baseDensity > 0) &&
1314            (opts.fitDensity > 0) && (srcImageInfo.baseDensity != opts.fitDensity);
1315 }
1316 
ImageSizeChange(int32_t width,int32_t height,int32_t desiredWidth,int32_t desiredHeight)1317 bool ImageSource::ImageSizeChange(int32_t width, int32_t height, int32_t desiredWidth, int32_t desiredHeight)
1318 {
1319     bool sizeChange = false;
1320     if (desiredWidth > 0 && desiredHeight > 0 && width > 0 && height > 0) {
1321         float scaleX = static_cast<float>(desiredWidth) / static_cast<float>(width);
1322         float scaleY = static_cast<float>(desiredHeight) / static_cast<float>(height);
1323         if ((fabs(scaleX - 1.0f) >= EPSILON) && (fabs(scaleY - 1.0f) >= EPSILON)) {
1324             sizeChange = true;
1325         }
1326     }
1327     return sizeChange;
1328 }
1329 
ImageConverChange(const Rect & cropRect,ImageInfo & dstImageInfo,ImageInfo & srcImageInfo)1330 bool ImageSource::ImageConverChange(const Rect &cropRect, ImageInfo &dstImageInfo, ImageInfo &srcImageInfo)
1331 {
1332     bool hasPixelConvert = false;
1333     dstImageInfo.alphaType = ImageUtils::GetValidAlphaTypeByFormat(dstImageInfo.alphaType, dstImageInfo.pixelFormat);
1334     if (dstImageInfo.pixelFormat != srcImageInfo.pixelFormat || dstImageInfo.alphaType != srcImageInfo.alphaType) {
1335         hasPixelConvert = true;
1336     }
1337     CropValue value = PostProc::GetCropValue(cropRect, srcImageInfo.size);
1338     if (value == CropValue::NOCROP && !hasPixelConvert) {
1339         IMAGE_LOGD("[ImageSource]no need crop and pixel convert.");
1340         return false;
1341     } else if (value == CropValue::INVALID) {
1342         IMAGE_LOGE("[ImageSource]invalid corp region, top:%{public}d, left:%{public}d, "
1343                    "width:%{public}d, height:%{public}d",
1344                    cropRect.top, cropRect.left, cropRect.width, cropRect.height);
1345         return false;
1346     }
1347     return true;
1348 }
DecodeBase64(const uint8_t * data,uint32_t size)1349 unique_ptr<SourceStream> ImageSource::DecodeBase64(const uint8_t *data, uint32_t size)
1350 {
1351     string data1(reinterpret_cast<const char*>(data), size);
1352     return DecodeBase64(data1);
1353 }
1354 
DecodeBase64(const string & data)1355 unique_ptr<SourceStream> ImageSource::DecodeBase64(const string &data)
1356 {
1357     if (data.size() < IMAGE_URL_PREFIX.size() ||
1358        (data.compare(0, IMAGE_URL_PREFIX.size(), IMAGE_URL_PREFIX) != 0)) {
1359         IMAGE_LOGD("[ImageSource]Base64 image header mismatch.");
1360         return nullptr;
1361     }
1362 
1363     size_t encoding = data.find(BASE64_URL_PREFIX, IMAGE_URL_PREFIX.size());
1364     if (encoding == data.npos) {
1365         IMAGE_LOGE("[ImageSource]Base64 mismatch.");
1366         return nullptr;
1367     }
1368     string b64Data = data.substr(encoding + BASE64_URL_PREFIX.size());
1369     size_t rawDataLen = b64Data.size() - count(b64Data.begin(), b64Data.end(), '=');
1370     rawDataLen -= (rawDataLen / INT_8) * INT_2;
1371 
1372     SkBase64 base64Decoder;
1373     if (base64Decoder.decode(b64Data.data(), b64Data.size()) != SkBase64::kNoError) {
1374         IMAGE_LOGE("[ImageSource]base64 image decode failed!");
1375         return nullptr;
1376     }
1377 
1378     auto base64Data = base64Decoder.getData();
1379     const uint8_t* imageData = reinterpret_cast<uint8_t*>(base64Data);
1380     IMAGE_LOGD("[ImageSource]Create BufferSource from decoded base64 string.");
1381     auto result = BufferSourceStream::CreateSourceStream(imageData, rawDataLen);
1382 
1383     if (base64Data != nullptr) {
1384         delete[] base64Data;
1385         base64Data = nullptr;
1386     }
1387     return result;
1388 }
1389 
IsSpecialYUV()1390 bool ImageSource::IsSpecialYUV()
1391 {
1392     const bool isBufferSource = (sourceStreamPtr_ != nullptr)
1393         && (sourceStreamPtr_->GetStreamType() == ImagePlugin::BUFFER_SOURCE_TYPE);
1394     const bool isSizeValid = (sourceOptions_.size.width > 0) && (sourceOptions_.size.height > 0);
1395     const bool isYUV = (sourceOptions_.pixelFormat == PixelFormat::NV12)
1396         || (sourceOptions_.pixelFormat == PixelFormat::NV21);
1397     return (isBufferSource && isSizeValid && isYUV);
1398 }
1399 
FloatToUint8(float f)1400 static inline uint8_t FloatToUint8(float f)
1401 {
1402     int data = static_cast<int>(f + 0.5f);
1403     if (data < 0) {
1404         data = 0;
1405     } else if (data > UINT8_MAX) {
1406         data = UINT8_MAX;
1407     }
1408     return static_cast<uint8_t>(data);
1409 }
1410 
ConvertYUV420ToRGBA(uint8_t * data,uint32_t size,bool isSupportOdd,bool isAddUV,uint32_t & errorCode)1411 bool ImageSource::ConvertYUV420ToRGBA(uint8_t *data, uint32_t size,
1412     bool isSupportOdd, bool isAddUV, uint32_t &errorCode)
1413 {
1414     IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA IN srcPixelFormat:%{public}d, srcSize:(%{public}d, %{public}d)",
1415         sourceOptions_.pixelFormat, sourceOptions_.size.width, sourceOptions_.size.height);
1416     if ((!isSupportOdd) && (sourceOptions_.size.width & 1) == 1) {
1417         IMAGE_LOGE("[ImageSource]ConvertYUV420ToRGBA odd width, %{public}d", sourceOptions_.size.width);
1418         errorCode = ERR_IMAGE_DATA_UNSUPPORT;
1419         return false;
1420     }
1421 
1422     const size_t width = sourceOptions_.size.width;
1423     const size_t height = sourceOptions_.size.height;
1424     const size_t uvwidth = (isSupportOdd && isAddUV) ? (width + (width & 1)) : width;
1425     const uint8_t *yuvPlane = sourceStreamPtr_->GetDataPtr();
1426     const size_t yuvSize = sourceStreamPtr_->GetStreamSize();
1427     const size_t ubase = width * height + ((sourceOptions_.pixelFormat == PixelFormat::NV21) ? 0 : 1);
1428     const size_t vbase = width * height + ((sourceOptions_.pixelFormat == PixelFormat::NV21) ? 1 : 0);
1429     IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA uvbase:(%{public}zu, %{public}zu), width:(%{public}zu, %{public}zu)",
1430         ubase, vbase, width, uvwidth);
1431 
1432     for (size_t h = 0; h < height; h++) {
1433         const size_t yline = h * width;
1434         const size_t uvline = (h >> 1) * uvwidth;
1435 
1436         for (size_t w = 0; w < width; w++) {
1437             const size_t ypos = yline + w;
1438             const size_t upos = ubase + uvline + (w & (~1));
1439             const size_t vpos = vbase + uvline + (w & (~1));
1440             const uint8_t y = (ypos < yuvSize) ? yuvPlane[ypos] : 0;
1441             const uint8_t u = (upos < yuvSize) ? yuvPlane[upos] : 0;
1442             const uint8_t v = (vpos < yuvSize) ? yuvPlane[vpos] : 0;
1443             // jpeg
1444             const uint8_t r = FloatToUint8((1.0f * y) + (1.402f * v) - (0.703749f * UINT8_MAX));
1445             const uint8_t g = FloatToUint8((1.0f * y) - (0.344136f * u) - (0.714136f * v) + (0.531211f * UINT8_MAX));
1446             const uint8_t b = FloatToUint8((1.0f * y) + (1.772f * u) - (0.889475f * UINT8_MAX));
1447 
1448             const size_t rgbpos = ypos << 2;
1449             if ((rgbpos + NUM_3) < size) {
1450                 data[rgbpos + NUM_0] = r;
1451                 data[rgbpos + NUM_1] = g;
1452                 data[rgbpos + NUM_2] = b;
1453                 data[rgbpos + NUM_3] = UINT8_MAX;
1454             }
1455         }
1456     }
1457     IMAGE_LOGD("[ImageSource]ConvertYUV420ToRGBA OUT");
1458     return true;
1459 }
1460 
CreatePixelMapForYUV(uint32_t & errorCode)1461 unique_ptr<PixelMap> ImageSource::CreatePixelMapForYUV(uint32_t &errorCode)
1462 {
1463     IMAGE_LOGD("[ImageSource]CreatePixelMapForYUV IN srcPixelFormat:%{public}d, srcSize:(%{public}d, %{public}d)",
1464         sourceOptions_.pixelFormat, sourceOptions_.size.width, sourceOptions_.size.height);
1465 
1466     unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
1467     if (pixelMap == nullptr) {
1468         IMAGE_LOGE("[ImageSource]create the pixel map unique_ptr fail.");
1469         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
1470         return nullptr;
1471     }
1472 
1473     ImageInfo info;
1474     info.baseDensity = sourceOptions_.baseDensity;
1475     info.size.width = sourceOptions_.size.width;
1476     info.size.height = sourceOptions_.size.height;
1477     info.pixelFormat = PixelFormat::RGBA_8888;
1478     info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
1479     errorCode = pixelMap->SetImageInfo(info);
1480     if (errorCode != SUCCESS) {
1481         IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
1482         return nullptr;
1483     }
1484 
1485     size_t bufferSize = static_cast<size_t>(pixelMap->GetWidth() * pixelMap->GetHeight() * pixelMap->GetPixelBytes());
1486     auto buffer = malloc(bufferSize);
1487     if (buffer == nullptr) {
1488         HiLog::Error(LABEL, "allocate memory size %{public}zu fail", bufferSize);
1489         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
1490         return nullptr;
1491     }
1492 
1493     pixelMap->SetEditable(false);
1494     pixelMap->SetPixelsAddr(buffer, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
1495 
1496     if (!ConvertYUV420ToRGBA(static_cast<uint8_t *>(buffer), bufferSize, false, false, errorCode)) {
1497         HiLog::Error(LABEL, "convert yuv420 to rgba issue");
1498         errorCode = ERROR;
1499         return nullptr;
1500     }
1501 
1502     IMAGE_LOGD("[ImageSource]CreatePixelMapForYUV OUT");
1503     return pixelMap;
1504 }
1505 } // namespace Media
1506 } // namespace OHOS
1507