• 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 "bytrace.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 
38 namespace OHOS {
39 namespace Media {
40 using namespace OHOS::HiviewDFX;
41 using namespace std;
42 using namespace ImagePlugin;
43 using namespace MultimediaPlugin;
44 
45 static const map<PixelFormat, PlPixelFormat> PIXEL_FORMAT_MAP = {
46     { PixelFormat::UNKNOWN, PlPixelFormat::UNKNOWN },     { PixelFormat::ARGB_8888, PlPixelFormat::ARGB_8888 },
47     { PixelFormat::ALPHA_8, PlPixelFormat::ALPHA_8 },     { PixelFormat::RGB_565, PlPixelFormat::RGB_565 },
48     { PixelFormat::RGBA_F16, PlPixelFormat::RGBA_F16 },   { PixelFormat::RGBA_8888, PlPixelFormat::RGBA_8888 },
49     { PixelFormat::BGRA_8888, PlPixelFormat::BGRA_8888 }, { PixelFormat::RGB_888, PlPixelFormat::RGB_888 },
50     { PixelFormat::NV21, PlPixelFormat::NV21 },           { PixelFormat::NV12, PlPixelFormat::NV12 },
51     { PixelFormat::CMYK, PlPixelFormat::CMYK }
52 };
53 
54 static const map<ColorSpace, PlColorSpace> COLOR_SPACE_MAP = {
55     { ColorSpace::UNKNOWN, PlColorSpace::UNKNOWN },
56     { ColorSpace::DISPLAY_P3, PlColorSpace::DISPLAY_P3 },
57     { ColorSpace::SRGB, PlColorSpace::SRGB },
58     { ColorSpace::LINEAR_SRGB, PlColorSpace::LINEAR_SRGB },
59     { ColorSpace::EXTENDED_SRGB, PlColorSpace::EXTENDED_SRGB },
60     { ColorSpace::LINEAR_EXTENDED_SRGB, PlColorSpace::LINEAR_EXTENDED_SRGB },
61     { ColorSpace::GENERIC_XYZ, PlColorSpace::GENERIC_XYZ },
62     { ColorSpace::GENERIC_LAB, PlColorSpace::GENERIC_LAB },
63     { ColorSpace::ACES, PlColorSpace::ACES },
64     { ColorSpace::ACES_CG, PlColorSpace::ACES_CG },
65     { ColorSpace::ADOBE_RGB_1998, PlColorSpace::ADOBE_RGB_1998 },
66     { ColorSpace::DCI_P3, PlColorSpace::DCI_P3 },
67     { ColorSpace::ITU_709, PlColorSpace::ITU_709 },
68     { ColorSpace::ITU_2020, PlColorSpace::ITU_2020 },
69     { ColorSpace::ROMM_RGB, PlColorSpace::ROMM_RGB },
70     { ColorSpace::NTSC_1953, PlColorSpace::NTSC_1953 },
71     { ColorSpace::SMPTE_C, PlColorSpace::SMPTE_C }
72 };
73 
74 namespace InnerFormat {
75     const string RAW_FORMAT = "image/x-raw";
76     const string EXTENDED_FORMAT = "image/x-skia";
77     const string RAW_EXTENDED_FORMATS[] = {
78         "image/x-sony-arw",
79         "image/x-canon-cr2",
80         "image/x-adobe-dng",
81         "image/x-nikon-nef",
82         "image/x-nikon-nrw",
83         "image/x-olympus-orf",
84         "image/x-fuji-raf",
85         "image/x-panasonic-rw2",
86         "image/x-pentax-pef",
87         "image/x-samsung-srw",
88     };
89 }
90 
91 PluginServer &ImageSource::pluginServer_ = ImageUtils::GetPluginServer();
92 ImageSource::FormatAgentMap ImageSource::formatAgentMap_ = InitClass();
93 
GetSupportedFormats(set<string> & formats)94 uint32_t ImageSource::GetSupportedFormats(set<string> &formats)
95 {
96     IMAGE_LOGD("[ImageSource]get supported image type.");
97 
98     formats.clear();
99     vector<ClassInfo> classInfos;
100     uint32_t ret = pluginServer_.PluginServerGetClassInfo<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT,
101                                                                            classInfos);
102     if (ret != SUCCESS) {
103         IMAGE_LOGE("[ImageSource]get class info from plugin server,ret:%{public}u.", ret);
104         return ret;
105     }
106 
107     for (auto &info : classInfos) {
108         map<string, AttrData> &capbility = info.capabilities;
109         auto iter = capbility.find(IMAGE_ENCODE_FORMAT);
110         if (iter == capbility.end()) {
111             continue;
112         }
113 
114         AttrData &attr = iter->second;
115         const string *format = nullptr;
116         if (attr.GetValue(format) != SUCCESS) {
117             IMAGE_LOGE("[ImageSource]attr data get format failed.");
118             continue;
119         }
120 
121         if (*format == InnerFormat::RAW_FORMAT) {
122             formats.insert(std::begin(InnerFormat::RAW_EXTENDED_FORMATS), std::end(InnerFormat::RAW_EXTENDED_FORMATS));
123         } else {
124             formats.insert(*format);
125         }
126     }
127     return SUCCESS;
128 }
129 
CreateImageSource(unique_ptr<istream> is,const SourceOptions & opts,uint32_t & errorCode)130 unique_ptr<ImageSource> ImageSource::CreateImageSource(unique_ptr<istream> is, const SourceOptions &opts,
131                                                        uint32_t &errorCode)
132 {
133 #if !defined(_WIN32) && !defined(_APPLE)
134     StartTrace(BYTRACE_TAG_ZIMAGE, "CreateImageSource by istream");
135 #endif
136     IMAGE_LOGD("[ImageSource]create Imagesource with stream.");
137 
138     unique_ptr<SourceStream> streamPtr = IstreamSourceStream::CreateSourceStream(move(is));
139     if (streamPtr == nullptr) {
140         IMAGE_LOGE("[ImageSource]failed to create istream source stream.");
141         errorCode = ERR_IMAGE_SOURCE_DATA;
142         return nullptr;
143     }
144 
145     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
146     if (sourcePtr == nullptr) {
147         IMAGE_LOGE("[ImageSource]failed to create ImageSource with stream.");
148         errorCode = ERR_IMAGE_SOURCE_DATA;
149         return nullptr;
150     }
151     errorCode = SUCCESS;
152 #if !defined(_WIN32) && !defined(_APPLE)
153     FinishTrace(BYTRACE_TAG_ZIMAGE);
154 #endif
155     return unique_ptr<ImageSource>(sourcePtr);
156 }
157 
CreateImageSource(const uint8_t * data,uint32_t size,const SourceOptions & opts,uint32_t & errorCode)158 unique_ptr<ImageSource> ImageSource::CreateImageSource(const uint8_t *data, uint32_t size, const SourceOptions &opts,
159                                                        uint32_t &errorCode)
160 {
161 #if !defined(_WIN32) && !defined(_APPLE)
162     StartTrace(BYTRACE_TAG_ZIMAGE, "CreateImageSource by data");
163 #endif
164     IMAGE_LOGD("[ImageSource]create Imagesource with buffer.");
165 
166     if (data == nullptr || size == 0) {
167         IMAGE_LOGE("[ImageSource]parameter error.");
168         errorCode = ERR_IMAGE_DATA_ABNORMAL;
169         return nullptr;
170     }
171 
172     unique_ptr<SourceStream> streamPtr = BufferSourceStream::CreateSourceStream(data, size);
173     if (streamPtr == nullptr) {
174         IMAGE_LOGE("[ImageSource]failed to create buffer source stream.");
175         errorCode = ERR_IMAGE_SOURCE_DATA;
176         return nullptr;
177     }
178 
179     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
180     if (sourcePtr == nullptr) {
181         IMAGE_LOGE("[ImageSource]failed to create ImageSource with buffer.");
182         errorCode = ERR_IMAGE_SOURCE_DATA;
183         return nullptr;
184     }
185     errorCode = SUCCESS;
186 #if !defined(_WIN32) && !defined(_APPLE)
187     FinishTrace(BYTRACE_TAG_ZIMAGE);
188 #endif
189     return unique_ptr<ImageSource>(sourcePtr);
190 }
191 
CreateImageSource(const std::string & pathName,const SourceOptions & opts,uint32_t & errorCode)192 unique_ptr<ImageSource> ImageSource::CreateImageSource(const std::string &pathName, const SourceOptions &opts,
193                                                        uint32_t &errorCode)
194 {
195 #if !defined(_WIN32) && !defined(_APPLE)
196     StartTrace(BYTRACE_TAG_ZIMAGE, "CreateImageSource by path");
197 #endif
198     IMAGE_LOGD("[ImageSource]create Imagesource with pathName.");
199 
200     unique_ptr<SourceStream> streamPtr = FileSourceStream::CreateSourceStream(pathName);
201     if (streamPtr == nullptr) {
202         IMAGE_LOGE("[ImageSource]failed to create file source stream.");
203         errorCode = ERR_IMAGE_SOURCE_DATA;
204         return nullptr;
205     }
206 
207     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
208     if (sourcePtr == nullptr) {
209         IMAGE_LOGE("[ImageSource]failed to create ImageSource with pathName.");
210         errorCode = ERR_IMAGE_SOURCE_DATA;
211         return nullptr;
212     }
213     errorCode = SUCCESS;
214 #if !defined(_WIN32) && !defined(_APPLE)
215     FinishTrace(BYTRACE_TAG_ZIMAGE);
216 #endif
217     return unique_ptr<ImageSource>(sourcePtr);
218 }
219 
CreateImageSource(const int fd,const SourceOptions & opts,uint32_t & errorCode)220 unique_ptr<ImageSource> ImageSource::CreateImageSource(const int fd, const SourceOptions &opts,
221                                                        uint32_t &errorCode)
222 {
223 #if !defined(_WIN32) && !defined(_APPLE)
224     StartTrace(BYTRACE_TAG_ZIMAGE, "CreateImageSource by fd");
225 #endif
226     unique_ptr<SourceStream> streamPtr = FileSourceStream::CreateSourceStream(fd);
227     if (streamPtr == nullptr) {
228         IMAGE_LOGE("[ImageSource]failed to create file source stream.");
229         errorCode = ERR_IMAGE_SOURCE_DATA;
230         return nullptr;
231     }
232     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts);
233     if (sourcePtr == nullptr) {
234         IMAGE_LOGE("[ImageSource]failed to create ImageSource by fd.");
235         errorCode = ERR_IMAGE_SOURCE_DATA;
236         return nullptr;
237     }
238     errorCode = SUCCESS;
239 #if !defined(_WIN32) && !defined(_APPLE)
240     FinishTrace(BYTRACE_TAG_ZIMAGE);
241 #endif
242     return unique_ptr<ImageSource>(sourcePtr);
243 }
CreateIncrementalImageSource(const IncrementalSourceOptions & opts,uint32_t & errorCode)244 unique_ptr<ImageSource> ImageSource::CreateIncrementalImageSource(const IncrementalSourceOptions &opts,
245                                                                   uint32_t &errorCode)
246 {
247     IMAGE_LOGD("[ImageSource]create incremental ImageSource.");
248 
249     unique_ptr<SourceStream> streamPtr = IncrementalSourceStream::CreateSourceStream(opts.incrementalMode);
250     if (streamPtr == nullptr) {
251         IMAGE_LOGE("[ImageSource]failed to create incremental source stream.");
252         errorCode = ERR_IMAGE_SOURCE_DATA;
253         return nullptr;
254     }
255 
256     ImageSource *sourcePtr = new (std::nothrow) ImageSource(std::move(streamPtr), opts.sourceOptions);
257     if (sourcePtr == nullptr) {
258         IMAGE_LOGE("[ImageSource]failed to create incremental ImageSource.");
259         errorCode = ERR_IMAGE_SOURCE_DATA;
260         return nullptr;
261     }
262     sourcePtr->SetIncrementalSource(true);
263     errorCode = SUCCESS;
264     return unique_ptr<ImageSource>(sourcePtr);
265 }
266 
Reset()267 void ImageSource::Reset()
268 {
269     // if use skia now, no need reset
270     if (mainDecoder_ != nullptr && mainDecoder_->HasProperty(SKIA_DECODER)) {
271         return;
272     }
273     imageStatusMap_.clear();
274     decodeState_ = SourceDecodingState::UNRESOLVED;
275     sourceStreamPtr_->Seek(0);
276     mainDecoder_ = nullptr;
277 }
278 
CreatePixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)279 unique_ptr<PixelMap> ImageSource::CreatePixelMap(uint32_t index, const DecodeOptions &opts, uint32_t &errorCode)
280 {
281 #if !defined(_WIN32) && !defined(_APPLE)
282     StartTrace(BYTRACE_TAG_ZIMAGE, "CreatePixelMap");
283 #endif
284     std::unique_lock<std::mutex> guard(decodingMutex_);
285     opts_ = opts;
286     bool useSkia = opts_.sampleSize != 1;
287     if (useSkia) {
288         // we need reset to initial state to choose correct decoder
289         Reset();
290     }
291     auto iter = GetValidImageStatus(index, errorCode);
292     if (iter == imageStatusMap_.end()) {
293         IMAGE_LOGE("[ImageSource]get valid image status fail on create pixel map, ret:%{public}u.", errorCode);
294         return nullptr;
295     }
296     // the mainDecoder_ may be borrowed by Incremental decoding, so needs to be checked.
297     if (InitMainDecoder() != SUCCESS) {
298         IMAGE_LOGE("[ImageSource]image decode plugin is null.");
299         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
300         return nullptr;
301     }
302     unique_ptr<PixelMap> pixelMap = make_unique<PixelMap>();
303     if (pixelMap == nullptr) {
304         IMAGE_LOGE("[ImageSource]create the pixel map unique_ptr fail.");
305         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
306         return nullptr;
307     }
308 
309     ImagePlugin::PlImageInfo plInfo;
310     errorCode = SetDecodeOptions(mainDecoder_, index, opts_, plInfo);
311     if (errorCode != SUCCESS) {
312         IMAGE_LOGE("[ImageSource]set decode options error (index:%{public}u), ret:%{public}u.", index, errorCode);
313         return nullptr;
314     }
315 
316     for (auto listener : decodeListeners_) {
317         guard.unlock();
318         listener->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
319         guard.lock();
320     }
321 
322     Size size = {
323         .width = plInfo.size.width,
324         .height = plInfo.size.height
325     };
326     PostProc::ValidCropValue(opts_.CropRect, size);
327     errorCode = UpdatePixelMapInfo(opts_, plInfo, *(pixelMap.get()));
328     if (errorCode != SUCCESS) {
329         IMAGE_LOGE("[ImageSource]update pixelmap info error ret:%{public}u.", errorCode);
330         return nullptr;
331     }
332 
333     DecodeContext context;
334     FinalOutputStep finalOutputStep;
335     if (!useSkia) {
336         bool hasNinePatch = mainDecoder_->HasProperty(NINE_PATCH);
337         finalOutputStep = GetFinalOutputStep(opts_, *(pixelMap.get()), hasNinePatch);
338         IMAGE_LOGD("[ImageSource]finalOutputStep:%{public}d. opts.allocatorType %{public}d",
339             finalOutputStep, opts_.allocatorType);
340 
341         if (finalOutputStep == FinalOutputStep::NO_CHANGE) {
342             context.allocatorType = opts_.allocatorType;
343         } else {
344             context.allocatorType = AllocatorType::HEAP_ALLOC;
345         }
346     }
347 
348     errorCode = mainDecoder_->Decode(index, context);
349     if (context.ifPartialOutput) {
350         for (auto listener : decodeListeners_) {
351             guard.unlock();
352             listener->OnEvent((int)DecodeEvent::EVENT_PARTIAL_DECODE);
353             guard.lock();
354         }
355     }
356     if (!useSkia) {
357         ninePatchInfo_.ninePatch = context.ninePatchContext.ninePatch;
358         ninePatchInfo_.patchSize = context.ninePatchContext.patchSize;
359     }
360     guard.unlock();
361     if (errorCode != SUCCESS) {
362         IMAGE_LOGE("[ImageSource]decode source fail, ret:%{public}u.", errorCode);
363         if (context.pixelsBuffer.buffer != nullptr) {
364             if (context.freeFunc != nullptr) {
365                 context.freeFunc(context.pixelsBuffer.buffer, context.pixelsBuffer.context,
366                                  context.pixelsBuffer.bufferSize);
367             } else {
368                 free(context.pixelsBuffer.buffer);
369             }
370         }
371         return nullptr;
372     }
373     pixelMap->SetPixelsAddr(context.pixelsBuffer.buffer, context.pixelsBuffer.context, context.pixelsBuffer.bufferSize,
374                             context.allocatorType, context.freeFunc);
375     DecodeOptions procOpts;
376     CopyOptionsToProcOpts(opts_, procOpts, *(pixelMap.get()));
377     PostProc postProc;
378     errorCode = postProc.DecodePostProc(procOpts, *(pixelMap.get()), finalOutputStep);
379     if (errorCode != SUCCESS) {
380         return nullptr;
381     }
382 
383     if (!context.ifPartialOutput) {
384         for (auto listener : decodeListeners_) {
385             listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
386         }
387     }
388 #if !defined(_WIN32) && !defined(_APPLE)
389     FinishTrace(BYTRACE_TAG_ZIMAGE);
390 #endif
391     return pixelMap;
392 }
393 
CreateIncrementalPixelMap(uint32_t index,const DecodeOptions & opts,uint32_t & errorCode)394 unique_ptr<IncrementalPixelMap> ImageSource::CreateIncrementalPixelMap(uint32_t index, const DecodeOptions &opts,
395                                                                        uint32_t &errorCode)
396 {
397     IncrementalPixelMap *incPixelMapPtr = new (std::nothrow) IncrementalPixelMap(index, opts, this);
398     if (incPixelMapPtr == nullptr) {
399         IMAGE_LOGE("[ImageSource]create the incremental pixel map unique_ptr fail.");
400         errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
401         return nullptr;
402     }
403     errorCode = SUCCESS;
404     return unique_ptr<IncrementalPixelMap>(incPixelMapPtr);
405 }
406 
PromoteDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,ImageDecodingState & state,uint8_t & decodeProgress)407 uint32_t ImageSource::PromoteDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
408                                       ImageDecodingState &state, uint8_t &decodeProgress)
409 {
410     state = ImageDecodingState::UNRESOLVED;
411     decodeProgress = 0;
412     uint32_t ret = SUCCESS;
413     std::unique_lock<std::mutex> guard(decodingMutex_);
414     opts_ = opts;
415     auto imageStatusIter = GetValidImageStatus(index, ret);
416     if (imageStatusIter == imageStatusMap_.end()) {
417         IMAGE_LOGE("[ImageSource]get valid image status fail on promote decoding, ret:%{public}u.", ret);
418         return ret;
419     }
420     auto incrementalRecordIter = incDecodingMap_.find(&pixelMap);
421     if (incrementalRecordIter == incDecodingMap_.end()) {
422         ret = AddIncrementalContext(pixelMap, incrementalRecordIter);
423         if (ret != SUCCESS) {
424             IMAGE_LOGE("[ImageSource]failed to add context on incremental decoding, ret:%{public}u.", ret);
425             return ret;
426         }
427     }
428     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::BASE_INFO_PARSED) {
429         IMAGE_LOGD("[ImageSource]promote decode : set decode options.");
430         ImagePlugin::PlImageInfo plInfo;
431         ret = SetDecodeOptions(incrementalRecordIter->second.decoder, index, opts_, plInfo);
432         if (ret != SUCCESS) {
433             IMAGE_LOGE("[ImageSource]set decode options error (image index:%{public}u), ret:%{public}u.", index, ret);
434             return ret;
435         }
436 
437         auto iter = decodeEventMap_.find((int)DecodeEvent::EVENT_HEADER_DECODE);
438         if (iter == decodeEventMap_.end()) {
439             decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_HEADER_DECODE, 1));
440             for (auto listener : decodeListeners_) {
441                 guard.unlock();
442                 listener->OnEvent((int)DecodeEvent::EVENT_HEADER_DECODE);
443                 guard.lock();
444             }
445         }
446         Size size = {
447             .width = plInfo.size.width,
448             .height = plInfo.size.height
449         };
450         PostProc::ValidCropValue(opts_.CropRect, size);
451         ret = UpdatePixelMapInfo(opts_, plInfo, pixelMap);
452         if (ret != SUCCESS) {
453             IMAGE_LOGE("[ImageSource]update pixelmap info error (image index:%{public}u), ret:%{public}u.", index, ret);
454             return ret;
455         }
456         incrementalRecordIter->second.IncrementalState = ImageDecodingState::IMAGE_DECODING;
457     }
458     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_DECODING) {
459         ret = DoIncrementalDecoding(index, opts_, pixelMap, incrementalRecordIter->second);
460         decodeProgress = incrementalRecordIter->second.decodingProgress;
461         state = incrementalRecordIter->second.IncrementalState;
462         if (isIncrementalCompleted_) {
463             PostProc postProc;
464             ret = postProc.DecodePostProc(opts_, pixelMap);
465             if (state == ImageDecodingState::IMAGE_DECODED) {
466                 auto iter = decodeEventMap_.find((int)DecodeEvent::EVENT_COMPLETE_DECODE);
467                 if (iter == decodeEventMap_.end()) {
468                     decodeEventMap_.insert(std::pair<int32_t, int32_t>((int)DecodeEvent::EVENT_COMPLETE_DECODE, 1));
469                     for (auto listener : decodeListeners_) {
470                         guard.unlock();
471                         listener->OnEvent((int)DecodeEvent::EVENT_COMPLETE_DECODE);
472                         guard.lock();
473                     }
474                 }
475             }
476         }
477         return ret;
478     }
479 
480     // IMAGE_ERROR or IMAGE_DECODED.
481     state = incrementalRecordIter->second.IncrementalState;
482     decodeProgress = incrementalRecordIter->second.decodingProgress;
483     if (incrementalRecordIter->second.IncrementalState == ImageDecodingState::IMAGE_ERROR) {
484         IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on incremental decoding.",
485                    incrementalRecordIter->second.IncrementalState);
486         return ERR_IMAGE_DECODE_ABNORMAL;
487     }
488     return SUCCESS;
489 }
490 
DetachIncrementalDecoding(PixelMap & pixelMap)491 void ImageSource::DetachIncrementalDecoding(PixelMap &pixelMap)
492 {
493     std::lock_guard<std::mutex> guard(decodingMutex_);
494     auto iter = incDecodingMap_.find(&pixelMap);
495     if (iter == incDecodingMap_.end()) {
496         return;
497     }
498 
499     if (mainDecoder_ == nullptr) {
500         // return back the decoder to mainDecoder_.
501         mainDecoder_ = std::move(iter->second.decoder);
502         iter->second.decoder = nullptr;
503     }
504     incDecodingMap_.erase(iter);
505 }
506 
UpdateData(const uint8_t * data,uint32_t size,bool isCompleted)507 uint32_t ImageSource::UpdateData(const uint8_t *data, uint32_t size, bool isCompleted)
508 {
509     if (sourceStreamPtr_ == nullptr) {
510         IMAGE_LOGE("[ImageSource]image source update data, source stream is null.");
511         return ERR_IMAGE_INVALID_PARAMETER;
512     }
513     std::lock_guard<std::mutex> guard(decodingMutex_);
514     if (isCompleted) {
515         isIncrementalCompleted_ = isCompleted;
516     }
517     return sourceStreamPtr_->UpdateData(data, size, isCompleted);
518 }
519 
GetDecodeEvent()520 DecodeEvent ImageSource::GetDecodeEvent()
521 {
522     return decodeEvent_;
523 }
524 
GetImageInfo(uint32_t index,ImageInfo & imageInfo)525 uint32_t ImageSource::GetImageInfo(uint32_t index, ImageInfo &imageInfo)
526 {
527     uint32_t ret = SUCCESS;
528     std::unique_lock<std::mutex> guard(decodingMutex_);
529     auto iter = GetValidImageStatus(index, ret);
530     if (iter == imageStatusMap_.end()) {
531         guard.unlock();
532         IMAGE_LOGE("[ImageSource]get valid image status fail on get image info, ret:%{public}u.", ret);
533         return ret;
534     }
535     ImageInfo &info = (iter->second).imageInfo;
536     if (info.size.width == 0 || info.size.height == 0) {
537         IMAGE_LOGE("[ImageSource]get the image size fail on get image info, width:%{public}d, height:%{public}d.",
538                    info.size.width, info.size.height);
539         return ERR_IMAGE_DECODE_FAILED;
540     }
541 
542     imageInfo = info;
543     return SUCCESS;
544 }
545 
ModifyImageProperty(uint32_t index,const std::string & key,const std::string & value,const std::string & path)546 uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
547     const std::string &value, const std::string &path)
548 {
549     std::unique_lock<std::mutex> guard(decodingMutex_);
550     uint32_t ret;
551     auto iter = GetValidImageStatus(0, ret);
552     if (iter == imageStatusMap_.end()) {
553         IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
554         return ret;
555     }
556     ret = mainDecoder_->ModifyImageProperty(index, key, value, path);
557     if (ret != SUCCESS) {
558         IMAGE_LOGE("[ImageSource] GetImagePropertyInt fail, ret:%{public}u", ret);
559         return ret;
560     }
561     return SUCCESS;
562 }
563 
GetImagePropertyInt(uint32_t index,const std::string & key,int32_t & value)564 uint32_t ImageSource::GetImagePropertyInt(uint32_t index, const std::string &key, int32_t &value)
565 {
566     std::unique_lock<std::mutex> guard(decodingMutex_);
567     uint32_t ret;
568     auto iter = GetValidImageStatus(0, ret);
569     if (iter == imageStatusMap_.end()) {
570         IMAGE_LOGE("[ImageSource]get valid image status fail on get image property, ret:%{public}u.", ret);
571         return ret;
572     }
573 
574     ret = mainDecoder_->GetImagePropertyInt(index, key, value);
575     if (ret != SUCCESS) {
576         IMAGE_LOGE("[ImageSource] GetImagePropertyInt fail, ret:%{public}u", ret);
577         return ret;
578     }
579 
580     return SUCCESS;
581 }
582 
GetImagePropertyString(uint32_t index,const std::string & key,std::string & value)583 uint32_t ImageSource::GetImagePropertyString(uint32_t index, const std::string &key, std::string &value)
584 {
585     std::unique_lock<std::mutex> guard(decodingMutex_);
586     uint32_t ret;
587     auto iter = GetValidImageStatus(0, ret);
588     if (iter == imageStatusMap_.end()) {
589         IMAGE_LOGE("[ImageSource]get valid image status fail on get image property, ret:%{public}u.", ret);
590         return ret;
591     }
592     ret = mainDecoder_->GetImagePropertyString(index, key, value);
593     if (ret != SUCCESS) {
594         IMAGE_LOGE("[ImageSource] GetImagePropertyInt fail, ret:%{public}u", ret);
595         return ret;
596     }
597     return SUCCESS;
598 }
GetSourceInfo(uint32_t & errorCode)599 const SourceInfo &ImageSource::GetSourceInfo(uint32_t &errorCode)
600 {
601     std::lock_guard<std::mutex> guard(decodingMutex_);
602     errorCode = DecodeSourceInfo(true);
603     return sourceInfo_;
604 }
605 
RegisterListener(PeerListener * listener)606 void ImageSource::RegisterListener(PeerListener *listener)
607 {
608     if (listener == nullptr) {
609         return;
610     }
611     std::lock_guard<std::mutex> guard(listenerMutex_);
612     listeners_.insert(listener);
613 }
614 
UnRegisterListener(PeerListener * listener)615 void ImageSource::UnRegisterListener(PeerListener *listener)
616 {
617     if (listener == nullptr) {
618         return;
619     }
620     std::lock_guard<std::mutex> guard(listenerMutex_);
621     auto iter = listeners_.find(listener);
622     if (iter != listeners_.end()) {
623         listeners_.erase(iter);
624     }
625 }
626 
AddDecodeListener(DecodeListener * listener)627 void ImageSource::AddDecodeListener(DecodeListener *listener)
628 {
629     if (listener == nullptr) {
630         IMAGE_LOGE("AddDecodeListener listener null");
631         return;
632     }
633     std::lock_guard<std::mutex> guard(listenerMutex_);
634     decodeListeners_.insert(listener);
635 }
636 
RemoveDecodeListener(DecodeListener * listener)637 void ImageSource::RemoveDecodeListener(DecodeListener *listener)
638 {
639     if (listener == nullptr) {
640         IMAGE_LOGE("RemoveDecodeListener listener null");
641         return;
642     }
643     std::lock_guard<std::mutex> guard(listenerMutex_);
644     auto iter = decodeListeners_.find(listener);
645     if (iter != decodeListeners_.end()) {
646         decodeListeners_.erase(iter);
647     }
648 }
649 
~ImageSource()650 ImageSource::~ImageSource()
651 {
652     std::lock_guard<std::mutex> guard(listenerMutex_);
653     for (const auto &listener : listeners_) {
654         listener->OnPeerDestory();
655     }
656 }
657 
IsStreamCompleted()658 bool ImageSource::IsStreamCompleted()
659 {
660     std::lock_guard<std::mutex> guard(decodingMutex_);
661     return sourceStreamPtr_->IsStreamCompleted();
662 }
663 
664 // ------------------------------- private method -------------------------------
ImageSource(unique_ptr<SourceStream> && stream,const SourceOptions & opts)665 ImageSource::ImageSource(unique_ptr<SourceStream> &&stream, const SourceOptions &opts)
666     : sourceStreamPtr_(stream.release())
667 {
668     sourceInfo_.encodedFormat = opts.formatHint;
669     sourceInfo_.baseDensity = opts.baseDensity;
670 }
671 
InitClass()672 ImageSource::FormatAgentMap ImageSource::InitClass()
673 {
674     vector<ClassInfo> classInfos;
675     pluginServer_.PluginServerGetClassInfo<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, classInfos);
676     set<string> formats;
677     for (auto &info : classInfos) {
678         auto &capabilities = info.capabilities;
679         auto iter = capabilities.find(IMAGE_ENCODE_FORMAT);
680         if (iter == capabilities.end()) {
681             continue;
682         }
683 
684         AttrData &attr = iter->second;
685         string format;
686         if (SUCCESS != attr.GetValue(format)) {
687             IMAGE_LOGE("[ImageSource]attr data get format:[%{public}s] failed.", format.c_str());
688             continue;
689         }
690         formats.insert(move(format));
691     }
692 
693     FormatAgentMap tempAgentMap;
694     AbsImageFormatAgent *formatAgent = nullptr;
695     for (auto format : formats) {
696         map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(format) } };
697         formatAgent =
698             pluginServer_.CreateObject<AbsImageFormatAgent>(AbsImageFormatAgent::SERVICE_DEFAULT, capabilities);
699         if (formatAgent == nullptr) {
700             continue;
701         }
702         tempAgentMap.insert(FormatAgentMap::value_type(std::move(format), formatAgent));
703     }
704     return tempAgentMap;
705 }
706 
CheckEncodedFormat(AbsImageFormatAgent & agent)707 uint32_t ImageSource::CheckEncodedFormat(AbsImageFormatAgent &agent)
708 {
709     uint32_t size = agent.GetHeaderSize();
710     ImagePlugin::DataStreamBuffer outData;
711     if (sourceStreamPtr_ == nullptr) {
712         IMAGE_LOGE("[ImageSource]check image format, source stream is null.");
713         return ERR_IMAGE_INVALID_PARAMETER;
714     }
715     if (!sourceStreamPtr_->Peek(size, outData)) {
716         IMAGE_LOGE("[ImageSource]stream peek the data fail.");
717         return ERR_IMAGE_SOURCE_DATA;
718     }
719 
720     if (outData.inputStreamBuffer == nullptr || outData.dataSize < size) {
721         IMAGE_LOGE("[ImageSource]the ouData is incomplete.");
722         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
723     }
724 
725     if (!agent.CheckFormat(outData.inputStreamBuffer, size)) {
726         IMAGE_LOGE("[ImageSource]check mismatched format :%{public}s.", agent.GetFormatType().c_str());
727         return ERR_IMAGE_MISMATCHED_FORMAT;
728     }
729     return SUCCESS;
730 }
731 
CheckFormatHint(const string & formatHint,FormatAgentMap::iterator & formatIter)732 uint32_t ImageSource::CheckFormatHint(const string &formatHint, FormatAgentMap::iterator &formatIter)
733 {
734     uint32_t ret = ERROR;
735     formatIter = formatAgentMap_.find(formatHint);
736     if (formatIter == formatAgentMap_.end()) {
737         IMAGE_LOGE("[ImageSource]check input format fail.");
738         return ret;
739     }
740     AbsImageFormatAgent *agent = formatIter->second;
741     ret = CheckEncodedFormat(*agent);
742     if (ret != SUCCESS) {
743         if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
744             IMAGE_LOGE("[ImageSource]image source incomplete.");
745         }
746         return ret;
747     }
748     return SUCCESS;
749 }
750 
GetEncodedFormat(const string & formatHint,string & format)751 uint32_t ImageSource::GetEncodedFormat(const string &formatHint, string &format)
752 {
753     bool streamIncomplete = false;
754     auto hintIter = formatAgentMap_.end();
755     if (!formatHint.empty()) {
756         uint32_t ret = CheckFormatHint(formatHint, hintIter);
757         if (ret == ERR_IMAGE_SOURCE_DATA) {
758             IMAGE_LOGE("[ImageSource]image source data error.");
759             return ret;
760         } else if (ret == SUCCESS) {
761             format = hintIter->first;
762             IMAGE_LOGD("[ImageSource]check input image format success, format:%{public}s.", format.c_str());
763             return SUCCESS;
764         } else if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
765             streamIncomplete = true;
766             IMAGE_LOGE("[ImageSource]image source data error ERR_IMAGE_SOURCE_DATA_INCOMPLETE.");
767         }
768     }
769 
770     for (auto iter = formatAgentMap_.begin(); iter != formatAgentMap_.end(); ++iter) {
771         string curFormat = iter->first;
772         if (iter == hintIter || curFormat == InnerFormat::RAW_FORMAT) {
773             continue;  // has been checked before.
774         }
775         AbsImageFormatAgent *agent = iter->second;
776         auto ret = CheckEncodedFormat(*agent);
777         if (ret == ERR_IMAGE_MISMATCHED_FORMAT) {
778             continue;
779         } else if (ret == SUCCESS) {
780             IMAGE_LOGI("[ImageSource]GetEncodedFormat success format :%{public}s.", iter->first.c_str());
781             format = iter->first;
782             return SUCCESS;
783         } else if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
784             streamIncomplete = true;
785         }
786     }
787 
788     if (streamIncomplete) {
789         IMAGE_LOGE("[ImageSource]image source incomplete.");
790         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
791     }
792 
793     // default return raw image
794     format = InnerFormat::RAW_FORMAT;
795     IMAGE_LOGI("[ImageSource]image default to raw format.");
796     return SUCCESS;
797 }
798 
OnSourceRecognized(bool isAcquiredImageNum)799 uint32_t ImageSource::OnSourceRecognized(bool isAcquiredImageNum)
800 {
801     uint32_t ret = InitMainDecoder();
802     if (ret != SUCCESS) {
803         sourceInfo_.state = SourceInfoState::UNSUPPORTED_FORMAT;
804         decodeState_ = SourceDecodingState::UNSUPPORTED_FORMAT;
805         IMAGE_LOGE("[ImageSource]image decode error, ret:[%{public}u].", ret);
806         return ret;
807     }
808 
809     // for raw image, we need check the original format after decoder initialzation
810     string value;
811     ret = mainDecoder_->GetImagePropertyString(0, ACTUAL_IMAGE_ENCODED_FORMAT, value);
812     if (ret == SUCCESS) {
813         // update new format
814         sourceInfo_.encodedFormat = value;
815         IMAGE_LOGI("[ImageSource] update new format, value:%{public}s", value.c_str());
816     } else {
817         IMAGE_LOGD("[ImageSource] GetImagePropertyString fail, ret:%{public}u", ret);
818     }
819 
820     if (isAcquiredImageNum) {
821         ret = mainDecoder_->GetTopLevelImageNum(sourceInfo_.topLevelImageNum);
822         if (ret != SUCCESS) {
823             if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
824                 sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
825                 IMAGE_LOGE("[ImageSource]image source data incomplete.");
826                 return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
827             }
828             sourceInfo_.state = SourceInfoState::FILE_INFO_ERROR;
829             decodeState_ = SourceDecodingState::FILE_INFO_ERROR;
830             IMAGE_LOGE("[ImageSource]image source error.");
831             return ret;
832         }
833     }
834     sourceInfo_.state = SourceInfoState::FILE_INFO_PARSED;
835     decodeState_ = SourceDecodingState::FILE_INFO_DECODED;
836     return SUCCESS;
837 }
838 
OnSourceUnresolved()839 uint32_t ImageSource::OnSourceUnresolved()
840 {
841     string formatResult;
842     auto ret = GetEncodedFormat(sourceInfo_.encodedFormat, formatResult);
843     if (ret != SUCCESS) {
844         if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
845             IMAGE_LOGE("[ImageSource]image source incomplete.");
846             sourceInfo_.state = SourceInfoState::SOURCE_INCOMPLETE;
847             return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
848         } else if (ret == ERR_IMAGE_UNKNOWN_FORMAT) {
849             IMAGE_LOGE("[ImageSource]image unknown format.");
850             sourceInfo_.state = SourceInfoState::UNKNOWN_FORMAT;
851             decodeState_ = SourceDecodingState::UNKNOWN_FORMAT;
852             return ERR_IMAGE_UNKNOWN_FORMAT;
853         }
854         sourceInfo_.state = SourceInfoState::SOURCE_ERROR;
855         decodeState_ = SourceDecodingState::SOURCE_ERROR;
856         IMAGE_LOGE("[ImageSource]image source error.");
857         return ret;
858     }
859     sourceInfo_.encodedFormat = formatResult;
860     decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
861     return SUCCESS;
862 }
863 
DecodeSourceInfo(bool isAcquiredImageNum)864 uint32_t ImageSource::DecodeSourceInfo(bool isAcquiredImageNum)
865 {
866     uint32_t ret = SUCCESS;
867     if (decodeState_ >= SourceDecodingState::FILE_INFO_DECODED) {
868         if (isAcquiredImageNum) {
869             decodeState_ = SourceDecodingState::FORMAT_RECOGNIZED;
870         } else {
871             return SUCCESS;
872         }
873     }
874     if (decodeState_ == SourceDecodingState::UNRESOLVED) {
875         ret = OnSourceUnresolved();
876         if (ret != SUCCESS) {
877             IMAGE_LOGE("[ImageSource]unresolved source: check format failed, ret:[%{public}d].", ret);
878             return ret;
879         }
880     }
881     if (decodeState_ == SourceDecodingState::FORMAT_RECOGNIZED) {
882         ret = OnSourceRecognized(isAcquiredImageNum);
883         if (ret != SUCCESS) {
884             IMAGE_LOGE("[ImageSource]recognized source: get source info failed, ret:[%{public}d].", ret);
885             return ret;
886         }
887         return SUCCESS;
888     }
889     IMAGE_LOGE("[ImageSource]invalid source state %{public}d on decode source info.", decodeState_);
890     switch (decodeState_) {
891         case SourceDecodingState::SOURCE_ERROR: {
892             ret = ERR_IMAGE_SOURCE_DATA;
893             break;
894         }
895         case SourceDecodingState::UNKNOWN_FORMAT: {
896             ret = ERR_IMAGE_UNKNOWN_FORMAT;
897             break;
898         }
899         case SourceDecodingState::UNSUPPORTED_FORMAT: {
900             ret = ERR_IMAGE_PLUGIN_CREATE_FAILED;
901             break;
902         }
903         case SourceDecodingState::FILE_INFO_ERROR: {
904             ret = ERR_IMAGE_DECODE_FAILED;
905             break;
906         }
907         default: {
908             ret = ERROR;
909             break;
910         }
911     }
912     return ret;
913 }
914 
DecodeImageInfo(uint32_t index,ImageStatusMap::iterator & iter)915 uint32_t ImageSource::DecodeImageInfo(uint32_t index, ImageStatusMap::iterator &iter)
916 {
917     uint32_t ret = DecodeSourceInfo(false);
918     if (ret != SUCCESS) {
919         IMAGE_LOGE("[ImageSource]decode the image fail, ret:%{public}d.", ret);
920         return ret;
921     }
922     if (mainDecoder_ == nullptr) {
923         IMAGE_LOGE("[ImageSource]get image size, image decode plugin is null.");
924         return ERR_IMAGE_PLUGIN_CREATE_FAILED;
925     }
926     ImagePlugin::PlSize size;
927     ret = mainDecoder_->GetImageSize(index, size);
928     if (ret == SUCCESS) {
929         ImageDecodingStatus imageStatus;
930         imageStatus.imageInfo.size.width = size.width;
931         imageStatus.imageInfo.size.height = size.height;
932         imageStatus.imageState = ImageDecodingState::BASE_INFO_PARSED;
933         auto result = imageStatusMap_.insert(ImageStatusMap::value_type(index, imageStatus));
934         iter = result.first;
935         return SUCCESS;
936     } else if (ret == ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
937         IMAGE_LOGE("[ImageSource]source data incomplete.");
938         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
939     } else {
940         ImageDecodingStatus imageStatus;
941         imageStatus.imageState = ImageDecodingState::BASE_INFO_ERROR;
942         auto result = imageStatusMap_.insert(ImageStatusMap::value_type(index, imageStatus));
943         iter = result.first;
944         IMAGE_LOGE("[ImageSource]decode the image info fail.");
945         return ERR_IMAGE_DECODE_FAILED;
946     }
947 }
948 
InitMainDecoder()949 uint32_t ImageSource::InitMainDecoder()
950 {
951     if (mainDecoder_ != nullptr) {
952         return SUCCESS;
953     }
954     uint32_t result = SUCCESS;
955     mainDecoder_ = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(result));
956     return result;
957 }
958 
CreateDecoder(uint32_t & errorCode)959 AbsImageDecoder *ImageSource::CreateDecoder(uint32_t &errorCode)
960 {
961     // in normal mode, we can get actual encoded format to the user
962     // but we need transfer to skia codec for adaption, "image/x-skia"
963     std::string encodedFormat = sourceInfo_.encodedFormat;
964     if (opts_.sampleSize != 1) {
965         encodedFormat = InnerFormat::EXTENDED_FORMAT;
966     }
967     map<string, AttrData> capabilities = { { IMAGE_ENCODE_FORMAT, AttrData(encodedFormat) } };
968     auto decoder = pluginServer_.CreateObject<AbsImageDecoder>(AbsImageDecoder::SERVICE_DEFAULT, capabilities);
969     if (decoder == nullptr) {
970         IMAGE_LOGE("[ImageSource]failed to create decoder object.");
971         errorCode = ERR_IMAGE_PLUGIN_CREATE_FAILED;
972         return nullptr;
973     }
974     errorCode = SUCCESS;
975     decoder->SetSource(*sourceStreamPtr_);
976     return decoder;
977 }
978 
SetDecodeOptions(std::unique_ptr<AbsImageDecoder> & decoder,uint32_t index,const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo)979 uint32_t ImageSource::SetDecodeOptions(std::unique_ptr<AbsImageDecoder> &decoder, uint32_t index,
980                                        const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo)
981 {
982     PixelDecodeOptions plOptions;
983     CopyOptionsToPlugin(opts, plOptions);
984     uint32_t ret = decoder->SetDecodeOptions(index, plOptions, plInfo);
985     if (ret != SUCCESS) {
986         IMAGE_LOGE("[ImageSource]decoder plugin set decode options fail (image index:%{public}u), ret:%{public}u.",
987                    index, ret);
988         return ret;
989     }
990     auto iter = imageStatusMap_.find(index);
991     if (iter != imageStatusMap_.end()) {
992         ImageInfo &info = (iter->second).imageInfo;
993         IMAGE_LOGD("[ImageSource]SetDecodeOptions plInfo.pixelFormat %{public}d", plInfo.pixelFormat);
994 
995         PlPixelFormat format = plInfo.pixelFormat;
996         auto find_item = std::find_if(PIXEL_FORMAT_MAP.begin(), PIXEL_FORMAT_MAP.end(),
997             [format](const std::map<PixelFormat, PlPixelFormat>::value_type item) {
998             return item.second == format;
999         });
1000         if (find_item != PIXEL_FORMAT_MAP.end()) {
1001             info.pixelFormat = (*find_item).first;
1002         }
1003         IMAGE_LOGD("[ImageSource]SetDecodeOptions info.pixelFormat %{public}d", info.pixelFormat);
1004     }
1005     return SUCCESS;
1006 }
1007 
UpdatePixelMapInfo(const DecodeOptions & opts,ImagePlugin::PlImageInfo & plInfo,PixelMap & pixelMap)1008 uint32_t ImageSource::UpdatePixelMapInfo(const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo,
1009                                          PixelMap &pixelMap)
1010 {
1011     pixelMap.SetEditable(opts.editable);
1012 
1013     ImageInfo info;
1014     info.baseDensity = sourceInfo_.baseDensity;
1015     info.size.width = plInfo.size.width;
1016     info.size.height = plInfo.size.height;
1017     info.pixelFormat = static_cast<PixelFormat>(plInfo.pixelFormat);
1018     info.alphaType = static_cast<AlphaType>(plInfo.alphaType);
1019     return pixelMap.SetImageInfo(info);
1020 }
1021 
CopyOptionsToPlugin(const DecodeOptions & opts,PixelDecodeOptions & plOpts)1022 void ImageSource::CopyOptionsToPlugin(const DecodeOptions &opts, PixelDecodeOptions &plOpts)
1023 {
1024     plOpts.CropRect.left = opts.CropRect.left;
1025     plOpts.CropRect.top = opts.CropRect.top;
1026     plOpts.CropRect.width = opts.CropRect.width;
1027     plOpts.CropRect.height = opts.CropRect.height;
1028     plOpts.desiredSize.width = opts.desiredSize.width;
1029     plOpts.desiredSize.height = opts.desiredSize.height;
1030     plOpts.rotateDegrees = opts.rotateDegrees;
1031     plOpts.sampleSize = opts.sampleSize;
1032     auto formatSearch = PIXEL_FORMAT_MAP.find(opts.desiredPixelFormat);
1033     plOpts.desiredPixelFormat =
1034         (formatSearch != PIXEL_FORMAT_MAP.end()) ? formatSearch->second : PlPixelFormat::RGBA_8888;
1035     auto colorSearch = COLOR_SPACE_MAP.find(opts.desiredColorSpace);
1036     plOpts.desiredColorSpace = (colorSearch != COLOR_SPACE_MAP.end()) ? colorSearch->second : PlColorSpace::UNKNOWN;
1037     plOpts.allowPartialImage = opts.allowPartialImage;
1038     plOpts.editable = opts.editable;
1039 }
1040 
CopyOptionsToProcOpts(const DecodeOptions & opts,DecodeOptions & procOpts,PixelMap & pixelMap)1041 void ImageSource::CopyOptionsToProcOpts(const DecodeOptions &opts, DecodeOptions &procOpts, PixelMap &pixelMap)
1042 {
1043     procOpts.fitDensity = opts.fitDensity;
1044     procOpts.CropRect.left = opts.CropRect.left;
1045     procOpts.CropRect.top = opts.CropRect.top;
1046     procOpts.CropRect.width = opts.CropRect.width;
1047     procOpts.CropRect.height = opts.CropRect.height;
1048     procOpts.desiredSize.width = opts.desiredSize.width;
1049     procOpts.desiredSize.height = opts.desiredSize.height;
1050     procOpts.rotateDegrees = opts.rotateDegrees;
1051     procOpts.sampleSize = opts.sampleSize;
1052     procOpts.desiredPixelFormat = opts.desiredPixelFormat;
1053     if (opts.allocatorType == AllocatorType::DEFAULT) {
1054         procOpts.allocatorType = AllocatorType::HEAP_ALLOC;
1055     } else {
1056         procOpts.allocatorType = opts.allocatorType;
1057     }
1058     procOpts.desiredColorSpace = opts.desiredColorSpace;
1059     procOpts.allowPartialImage = opts.allowPartialImage;
1060     procOpts.editable = opts.editable;
1061     // we need preference_ when post processing
1062     procOpts.preference = preference_;
1063 }
1064 
GetValidImageStatus(uint32_t index,uint32_t & errorCode)1065 ImageSource::ImageStatusMap::iterator ImageSource::GetValidImageStatus(uint32_t index, uint32_t &errorCode)
1066 {
1067     auto iter = imageStatusMap_.find(index);
1068     if (iter == imageStatusMap_.end()) {
1069         errorCode = DecodeImageInfo(index, iter);
1070         if (errorCode != SUCCESS) {
1071             IMAGE_LOGE("[ImageSource]image info decode fail, ret:%{public}u.", errorCode);
1072             return imageStatusMap_.end();
1073         }
1074     } else if (iter->second.imageState < ImageDecodingState::BASE_INFO_PARSED) {
1075         IMAGE_LOGE("[ImageSource]invalid imageState %{public}d on get image status.", iter->second.imageState);
1076         errorCode = ERR_IMAGE_DECODE_FAILED;
1077         return imageStatusMap_.end();
1078     }
1079     errorCode = SUCCESS;
1080     return iter;
1081 }
1082 
AddIncrementalContext(PixelMap & pixelMap,IncrementalRecordMap::iterator & iterator)1083 uint32_t ImageSource::AddIncrementalContext(PixelMap &pixelMap, IncrementalRecordMap::iterator &iterator)
1084 {
1085     uint32_t ret = SUCCESS;
1086     IncrementalDecodingContext context;
1087     if (mainDecoder_ != nullptr) {
1088         // borrowed decoder from the mainDecoder_.
1089         context.decoder = std::move(mainDecoder_);
1090     } else {
1091         context.decoder = std::unique_ptr<ImagePlugin::AbsImageDecoder>(CreateDecoder(ret));
1092     }
1093     if (context.decoder == nullptr) {
1094         IMAGE_LOGE("[ImageSource]failed to create decoder on add incremental context, ret:%{public}u.", ret);
1095         return ret;
1096     }
1097     // mainDecoder has parsed base info in DecodeImageInfo();
1098     context.IncrementalState = ImageDecodingState::BASE_INFO_PARSED;
1099     auto result = incDecodingMap_.insert(IncrementalRecordMap::value_type(&pixelMap, std::move(context)));
1100     iterator = result.first;
1101     return SUCCESS;
1102 }
1103 
DoIncrementalDecoding(uint32_t index,const DecodeOptions & opts,PixelMap & pixelMap,IncrementalDecodingContext & recordContext)1104 uint32_t ImageSource::DoIncrementalDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap,
1105                                             IncrementalDecodingContext &recordContext)
1106 {
1107     IMAGE_LOGD("[ImageSource]do incremental decoding: begin.");
1108     uint8_t *pixelAddr = static_cast<uint8_t *>(pixelMap.GetWritablePixels());
1109     ProgDecodeContext context;
1110     context.decodeContext.pixelsBuffer.buffer = pixelAddr;
1111     uint32_t ret = recordContext.decoder->PromoteIncrementalDecode(index, context);
1112     if (context.decodeContext.pixelsBuffer.buffer != nullptr && pixelAddr == nullptr) {
1113         pixelMap.SetPixelsAddr(context.decodeContext.pixelsBuffer.buffer, context.decodeContext.pixelsBuffer.context,
1114                                context.decodeContext.pixelsBuffer.bufferSize, context.decodeContext.allocatorType,
1115                                context.decodeContext.freeFunc);
1116     }
1117     IMAGE_LOGD("[ImageSource]do incremental decoding progress:%{public}u.", context.totalProcessProgress);
1118     recordContext.decodingProgress = context.totalProcessProgress;
1119     if (ret != SUCCESS && ret != ERR_IMAGE_SOURCE_DATA_INCOMPLETE) {
1120         recordContext.IncrementalState = ImageDecodingState::IMAGE_ERROR;
1121         IMAGE_LOGE("[ImageSource]do incremental decoding source fail, ret:%{public}u.", ret);
1122         return ret;
1123     }
1124     if (ret == SUCCESS) {
1125         recordContext.IncrementalState = ImageDecodingState::IMAGE_DECODED;
1126         IMAGE_LOGI("[ImageSource]do incremental decoding success.");
1127     }
1128     return ret;
1129 }
1130 
GetNinePatchInfo() const1131 const NinePatchInfo &ImageSource::GetNinePatchInfo() const
1132 {
1133     return ninePatchInfo_;
1134 }
1135 
SetMemoryUsagePreference(const MemoryUsagePreference preference)1136 void ImageSource::SetMemoryUsagePreference(const MemoryUsagePreference preference)
1137 {
1138     preference_ = preference;
1139 }
1140 
GetMemoryUsagePreference()1141 MemoryUsagePreference ImageSource::GetMemoryUsagePreference()
1142 {
1143     return preference_;
1144 }
1145 
SetIncrementalSource(const bool isIncrementalSource)1146 void ImageSource::SetIncrementalSource(const bool isIncrementalSource)
1147 {
1148     isIncrementalSource_ = isIncrementalSource;
1149 }
1150 
IsIncrementalSource()1151 bool ImageSource::IsIncrementalSource()
1152 {
1153     return isIncrementalSource_;
1154 }
1155 
GetFinalOutputStep(const DecodeOptions & opts,PixelMap & pixelMap,bool hasNinePatch)1156 FinalOutputStep ImageSource::GetFinalOutputStep(const DecodeOptions &opts, PixelMap &pixelMap, bool hasNinePatch)
1157 {
1158     ImageInfo info;
1159     pixelMap.GetImageInfo(info);
1160     ImageInfo dstImageInfo;
1161     dstImageInfo.size = opts.desiredSize;
1162     dstImageInfo.pixelFormat = opts.desiredPixelFormat;
1163     if (opts.desiredPixelFormat == PixelFormat::UNKNOWN) {
1164         if (preference_ == MemoryUsagePreference::LOW_RAM && info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
1165             dstImageInfo.pixelFormat = PixelFormat::RGB_565;
1166         } else {
1167             dstImageInfo.pixelFormat = PixelFormat::RGBA_8888;
1168         }
1169     }
1170     // decode use, this value may be changed by real pixelFormat
1171     if (pixelMap.GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) {
1172         dstImageInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
1173     } else {
1174         dstImageInfo.alphaType = pixelMap.GetAlphaType();
1175     }
1176     bool densityChange = HasDensityChange(opts, info, hasNinePatch);
1177     bool sizeChange = ImageSizeChange(pixelMap.GetWidth(), pixelMap.GetHeight(),
1178                                       opts.desiredSize.width, opts.desiredSize.height);
1179     bool rotateChange = !ImageUtils::FloatCompareZero(opts.rotateDegrees);
1180     bool convertChange = ImageConverChange(opts.CropRect, dstImageInfo, info);
1181     if (sizeChange) {
1182         return FinalOutputStep::SIZE_CHANGE;
1183     } else if (densityChange) {
1184         return FinalOutputStep::DENSITY_CHANGE;
1185     }
1186     if (rotateChange) {
1187         return FinalOutputStep::ROTATE_CHANGE;
1188     }
1189     if (convertChange) {
1190         return FinalOutputStep::CONVERT_CHANGE;
1191     }
1192     return FinalOutputStep::NO_CHANGE;
1193 }
1194 
HasDensityChange(const DecodeOptions & opts,ImageInfo & srcImageInfo,bool hasNinePatch)1195 bool ImageSource::HasDensityChange(const DecodeOptions &opts, ImageInfo &srcImageInfo, bool hasNinePatch)
1196 {
1197     return !hasNinePatch && (srcImageInfo.baseDensity > 0) &&
1198            (opts.fitDensity > 0) && (srcImageInfo.baseDensity != opts.fitDensity);
1199 }
1200 
ImageSizeChange(int32_t width,int32_t height,int32_t desiredWidth,int32_t desiredHeight)1201 bool ImageSource::ImageSizeChange(int32_t width, int32_t height, int32_t desiredWidth, int32_t desiredHeight)
1202 {
1203     bool sizeChange = false;
1204     if (desiredWidth > 0 && desiredHeight > 0 && width > 0 && height > 0) {
1205         float scaleX = static_cast<float>(desiredWidth) / static_cast<float>(width);
1206         float scaleY = static_cast<float>(desiredHeight) / static_cast<float>(height);
1207         if ((fabs(scaleX - 1.0f) >= EPSILON) && (fabs(scaleY - 1.0f) >= EPSILON)) {
1208             sizeChange = true;
1209         }
1210     }
1211     return sizeChange;
1212 }
1213 
ImageConverChange(const Rect & cropRect,ImageInfo & dstImageInfo,ImageInfo & srcImageInfo)1214 bool ImageSource::ImageConverChange(const Rect &cropRect, ImageInfo &dstImageInfo, ImageInfo &srcImageInfo)
1215 {
1216     bool hasPixelConvert = false;
1217     dstImageInfo.alphaType = ImageUtils::GetValidAlphaTypeByFormat(dstImageInfo.alphaType, dstImageInfo.pixelFormat);
1218     if (dstImageInfo.pixelFormat != srcImageInfo.pixelFormat || dstImageInfo.alphaType != srcImageInfo.alphaType) {
1219         hasPixelConvert = true;
1220     }
1221     CropValue value = PostProc::GetCropValue(cropRect, srcImageInfo.size);
1222     if (value == CropValue::NOCROP && !hasPixelConvert) {
1223         IMAGE_LOGD("[ImageSource]no need crop and pixel convert.");
1224         return false;
1225     } else if (value == CropValue::INVALID) {
1226         IMAGE_LOGE("[ImageSource]invalid corp region, top:%{public}d, left:%{public}d, "
1227                    "width:%{public}d, height:%{public}d",
1228                    cropRect.top, cropRect.left, cropRect.width, cropRect.height);
1229         return false;
1230     }
1231     return true;
1232 }
1233 } // namespace Media
1234 } // namespace OHOS
1235