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