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