1 /*
2 * Copyright (C) 2024 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 "common_utils.h"
17
18 #include <charconv>
19
20 #include "effect_log.h"
21 #include "effect_buffer.h"
22 #include "image_source.h"
23 #include "uri.h"
24 #include "string_helper.h"
25 #include "memcpy_helper.h"
26 #include "colorspace_helper.h"
27 #include "render_environment.h"
28 #include "format_helper.h"
29 #include "exif_metadata.h"
30
31 namespace OHOS {
32 namespace Media {
33 namespace Effect {
34 namespace {
35 const std::string IMAGE_LENGTH = "ImageLength";
36 const std::string IMAGE_WIDTH = "ImageWidth";
37 const std::string DATE_TIME = "DateTime";
38 const std::string PIXEL_X_DIMENSION = "PixelXDimension";
39 const std::string PIXEL_Y_DIMENSION = "PixelYDimension";
40 const int32_t TIME_MAX = 64;
41 }
42
43 using namespace OHOS::ColorManager;
44 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
45
46 const std::unordered_map<PixelFormat, IEffectFormat> CommonUtils::pixelFmtToEffectFmt_ = {
47 { PixelFormat::RGBA_8888, IEffectFormat::RGBA8888 },
48 { PixelFormat::NV21, IEffectFormat::YUVNV21 },
49 { PixelFormat::NV12, IEffectFormat::YUVNV12 },
50 { PixelFormat::RGBA_1010102, IEffectFormat::RGBA_1010102 },
51 };
52
53 const std::unordered_map<GraphicPixelFormat, IEffectFormat> CommonUtils::surfaceBufferFmtToEffectFmt_ = {
54 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888, IEffectFormat::RGBA8888},
55 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCBCR_420_SP, IEffectFormat::YUVNV12 },
56 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCRCB_420_SP, IEffectFormat::YUVNV21 },
57 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_1010102, IEffectFormat::RGBA_1010102 },
58 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCBCR_P010, IEffectFormat::YCBCR_P010 },
59 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCRCB_P010, IEffectFormat::YCRCB_P010 },
60 };
61
62 const std::unordered_map<AllocatorType, BufferType> CommonUtils::allocatorTypeToEffectBuffType_ = {
63 { AllocatorType::HEAP_ALLOC, BufferType::HEAP_MEMORY },
64 { AllocatorType::DMA_ALLOC, BufferType::DMA_BUFFER },
65 { AllocatorType::SHARE_MEM_ALLOC, BufferType::SHARED_MEMORY },
66 };
67
68 template <class ValueType>
ParseJson(const std::string & key,Plugin::Any & any,EffectJsonPtr & json)69 ErrorCode ParseJson(const std::string &key, Plugin::Any &any, EffectJsonPtr &json)
70 {
71 auto result = Plugin::AnyCast<ValueType>(&any);
72 if (result == nullptr) {
73 return ErrorCode::ERR_ANY_CAST_TYPE_NOT_MATCH;
74 }
75
76 json->Put(key, *result);
77 return ErrorCode::SUCCESS;
78 }
79
LockPixelMap(PixelMap * pixelMap,std::shared_ptr<EffectBuffer> & effectBuffer)80 ErrorCode CommonUtils::LockPixelMap(PixelMap *pixelMap, std::shared_ptr<EffectBuffer> &effectBuffer)
81 {
82 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "pixelMap is null!");
83 ColorSpaceName colorSpaceName = pixelMap->InnerGetGrColorSpacePtr() == nullptr ? ColorSpaceName::NONE :
84 pixelMap->InnerGetGrColorSpacePtr()->GetColorSpaceName();
85 EFFECT_LOGD("pixelMapInfos: width=%{public}d, height=%{public}d, formatType=%{public}d " \
86 "rowStride=%{public}d, byteCount=%{public}d, addr=%{private}p, colorSpaceName=%{public}d",
87 pixelMap->GetWidth(), pixelMap->GetHeight(), pixelMap->GetPixelFormat(), pixelMap->GetRowStride(),
88 pixelMap->GetByteCount(), pixelMap->GetPixels(), colorSpaceName);
89
90 IEffectFormat formatType = SwitchToEffectFormat(pixelMap->GetPixelFormat());
91 if (formatType == IEffectFormat::DEFAULT) {
92 EFFECT_LOGE("pixelFormat not support! pixelFormat=%{public}d", pixelMap->GetPixelFormat());
93 return ErrorCode::ERR_UNSUPPORTED_PIXEL_FORMAT;
94 }
95
96 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
97 bufferInfo->width_ = static_cast<uint32_t>(pixelMap->GetWidth());
98 bufferInfo->height_ = static_cast<uint32_t>(pixelMap->GetHeight());
99 bufferInfo->rowStride_ = static_cast<uint32_t>(pixelMap->GetRowStride());
100 bufferInfo->len_ = FormatHelper::CalculateSize(bufferInfo->width_, bufferInfo->height_, formatType);
101 bufferInfo->formatType_ = formatType;
102 bufferInfo->colorSpace_ = ColorSpaceHelper::ConvertToEffectColorSpace(colorSpaceName);
103
104 uint8_t *pixels = const_cast<uint8_t *>(pixelMap->GetPixels());
105 void *srcData = static_cast<void *>(pixels);
106 CHECK_AND_RETURN_RET_LOG(srcData != nullptr, ErrorCode::ERR_PIXELMAP_ACCESSPIXELS_FAIL, "fail exec GetPixels!");
107
108 EFFECT_LOGI("pixelMap bufferInfos: width=%{public}d, height=%{public}d, formatType=%{public}d, " \
109 "rowStride_=%{public}d, len=%{public}d, colorspace=%{public}d, addr=%{private}p",
110 bufferInfo->width_, bufferInfo->height_, bufferInfo->formatType_, bufferInfo->rowStride_,
111 bufferInfo->len_, bufferInfo->colorSpace_, pixels);
112
113 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
114 extraInfo->dataType = DataType::PIXEL_MAP;
115 extraInfo->bufferType = SwitchToEffectBuffType(pixelMap->GetAllocatorType());
116 extraInfo->pixelMap = pixelMap;
117 extraInfo->surfaceBuffer = nullptr;
118 if (extraInfo->bufferType == BufferType::DMA_BUFFER && pixelMap->GetFd() != nullptr) {
119 extraInfo->surfaceBuffer = reinterpret_cast<SurfaceBuffer*> (pixelMap->GetFd());
120 }
121 if (extraInfo->bufferType == BufferType::SHARED_MEMORY && pixelMap->GetFd() != nullptr) {
122 extraInfo->fd = reinterpret_cast<int *>(pixelMap->GetFd());
123 }
124 EFFECT_LOGI("pixelMap extraInfos: dataType=%{public}d, bufferType=%{public}d",
125 extraInfo->dataType, extraInfo->bufferType);
126
127 if (extraInfo->surfaceBuffer != nullptr) {
128 SurfaceBuffer *sb = extraInfo->surfaceBuffer;
129 EFFECT_LOGD("pixelMap surfaceBufferInfo: width=%{public}d, height=%{public}d, format=%{public}d, "
130 "rowStride=%{public}d, size=%{public}d, addr=%{private}p", sb->GetWidth(),
131 sb->GetHeight(), sb->GetFormat(), sb->GetStride(), sb->GetSize(), sb->GetVirAddr());
132 }
133
134 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, srcData, extraInfo);
135 return ErrorCode::SUCCESS;
136 }
137
ParseNativeWindowData(std::shared_ptr<EffectBuffer> & effectBuffer,const DataType & dataType)138 ErrorCode CommonUtils::ParseNativeWindowData(std::shared_ptr<EffectBuffer> &effectBuffer, const DataType &dataType)
139 {
140 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
141 bufferInfo->width_ = 0;
142 bufferInfo->height_ = 0;
143 bufferInfo->rowStride_ = 0;
144 bufferInfo->len_ = 0;
145 bufferInfo->formatType_ = IEffectFormat::DEFAULT;
146 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
147 extraInfo->dataType = dataType;
148 extraInfo->bufferType = BufferType::DMA_BUFFER;
149 extraInfo->pixelMap = nullptr;
150 extraInfo->surfaceBuffer = nullptr;
151 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, nullptr, extraInfo);
152 return ErrorCode::SUCCESS;
153 }
154
ParseSurfaceData(OHOS::SurfaceBuffer * surfaceBuffer,std::shared_ptr<EffectBuffer> & effectBuffer,const DataType & dataType,int64_t timestamp)155 ErrorCode CommonUtils::ParseSurfaceData(OHOS::SurfaceBuffer *surfaceBuffer,
156 std::shared_ptr<EffectBuffer> &effectBuffer, const DataType &dataType, int64_t timestamp)
157 {
158 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, ErrorCode::ERR_INPUT_NULL, "surfaceBuffer is null!");
159
160 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
161 bufferInfo->width_ = static_cast<uint32_t>(surfaceBuffer->GetWidth());
162 bufferInfo->height_ = static_cast<uint32_t>(surfaceBuffer->GetHeight());
163 bufferInfo->rowStride_ = static_cast<uint32_t>(surfaceBuffer->GetStride());
164 bufferInfo->len_ = surfaceBuffer->GetSize();
165 bufferInfo->formatType_ = SwitchToEffectFormat((GraphicPixelFormat)surfaceBuffer->GetFormat());
166 CM_ColorSpaceType colorSpaceType = CM_ColorSpaceType::CM_COLORSPACE_NONE;
167 ColorSpaceHelper::GetSurfaceBufferColorSpaceType(surfaceBuffer, colorSpaceType);
168 bufferInfo->colorSpace_ = ColorSpaceHelper::ConvertToEffectColorSpace(colorSpaceType);
169
170 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
171 extraInfo->dataType = dataType;
172 extraInfo->bufferType = BufferType::DMA_BUFFER;
173 extraInfo->pixelMap = nullptr;
174 extraInfo->surfaceBuffer = surfaceBuffer;
175 extraInfo->timestamp = timestamp;
176
177 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, surfaceBuffer->GetVirAddr(), extraInfo);
178 EFFECT_LOGI("surfaceBuffer width=%{public}d, height=%{public}d, stride=%{public}d, format=%{public}d, "
179 "size=%{public}d, usage = %{public}llu, addr=%{private}p, colorSpace=%{public}d",
180 surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), surfaceBuffer->GetStride(), surfaceBuffer->GetFormat(),
181 surfaceBuffer->GetSize(), static_cast<unsigned long long>(surfaceBuffer->GetUsage()),
182 surfaceBuffer->GetVirAddr(), colorSpaceType);
183 return ErrorCode::SUCCESS;
184 }
185
UrlToPath(const std::string & url)186 std::string CommonUtils::UrlToPath(const std::string &url)
187 {
188 OHOS::Uri uri = OHOS::Uri(url);
189 return uri.GetPath();
190 }
191
ParseUri(std::string & uri,std::shared_ptr<EffectBuffer> & effectBuffer,bool isOutputData)192 ErrorCode CommonUtils::ParseUri(std::string &uri, std::shared_ptr<EffectBuffer> &effectBuffer, bool isOutputData)
193 {
194 if (isOutputData) {
195 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
196 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
197 extraInfo->dataType = DataType::URI;
198 extraInfo->uri = std::move(uri);
199 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, nullptr, extraInfo);
200 return ErrorCode::SUCCESS;
201 }
202
203 auto path = UrlToPath(uri);
204 ErrorCode res = ParsePath(path, effectBuffer, isOutputData);
205 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res,
206 "ParseUri: path name fail! uri=%{public}s, res=%{public}d", uri.c_str(), res);
207
208 CHECK_AND_RETURN_RET_LOG(effectBuffer->extraInfo_ != nullptr, ErrorCode::ERR_EXTRA_INFO_NULL,
209 "ParseUri: extra info is null! uri=%{public}s", uri.c_str());
210 effectBuffer->extraInfo_->dataType = DataType::URI;
211 effectBuffer->extraInfo_->uri = std::move(uri);
212
213 return ErrorCode::SUCCESS;
214 }
215
ParsePath(std::string & path,std::shared_ptr<EffectBuffer> & effectBuffer,bool isOutputData)216 ErrorCode CommonUtils::ParsePath(std::string &path, std::shared_ptr<EffectBuffer> &effectBuffer,
217 bool isOutputData)
218 {
219 if (isOutputData) {
220 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
221 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
222 extraInfo->dataType = DataType::PATH;
223 extraInfo->path = std::move(path);
224 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, nullptr, extraInfo);
225 return ErrorCode::SUCCESS;
226 }
227
228 SourceOptions opts;
229 uint32_t errorCode = 0;
230 std::unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(path, opts, errorCode);
231 CHECK_AND_RETURN_RET_LOG(imageSource != nullptr, ErrorCode::ERR_CREATE_IMAGESOURCE_FAIL,
232 "ImageSource::CreateImageSource fail! path=%{public}s, errorCode=%{public}d", path.c_str(), errorCode);
233
234 DecodeOptions options;
235 options.desiredDynamicRange = DecodeDynamicRange::AUTO;
236 std::unique_ptr<PixelMap> pixelMap = imageSource->CreatePixelMap(options, errorCode);
237 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_CREATE_PIXELMAP_FAIL,
238 "CreatePixelMap fail! path=%{public}s, errorCode=%{public}d", path.c_str(), errorCode);
239
240 ErrorCode res = LockPixelMap(pixelMap.get(), effectBuffer);
241 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res,
242 "ParsePath: lock pixel map fail! path=%{public}s, res=%{public}d", path.c_str(), res);
243
244 CHECK_AND_RETURN_RET_LOG(effectBuffer->extraInfo_ != nullptr, ErrorCode::ERR_EXTRA_INFO_NULL,
245 "ParsePath: extra info is null! uri=%{public}s", path.c_str());
246 effectBuffer->extraInfo_->dataType = DataType::PATH;
247 effectBuffer->extraInfo_->path = std::move(path);
248 effectBuffer->extraInfo_->pixelMap = nullptr;
249 effectBuffer->extraInfo_->innerPixelMap = std::move(pixelMap);
250
251 return ErrorCode::SUCCESS;
252 }
253
SwitchToEffectFormat(GraphicPixelFormat pixelFormat)254 IEffectFormat CommonUtils::SwitchToEffectFormat(GraphicPixelFormat pixelFormat)
255 {
256 IEffectFormat formatType = IEffectFormat::DEFAULT;
257
258 auto itr = surfaceBufferFmtToEffectFmt_.find(pixelFormat);
259 if (itr != surfaceBufferFmtToEffectFmt_.end()) {
260 formatType = itr->second;
261 }
262
263 return formatType;
264 }
265
SwitchToEffectFormat(PixelFormat pixelFormat)266 IEffectFormat CommonUtils::SwitchToEffectFormat(PixelFormat pixelFormat)
267 {
268 IEffectFormat formatType = IEffectFormat::DEFAULT;
269
270 auto itr = pixelFmtToEffectFmt_.find(pixelFormat);
271 if (itr != pixelFmtToEffectFmt_.end()) {
272 formatType = itr->second;
273 }
274
275 return formatType;
276 }
277
SwitchToGraphicPixelFormat(IEffectFormat formatType)278 GraphicPixelFormat CommonUtils::SwitchToGraphicPixelFormat(IEffectFormat formatType)
279 {
280 GraphicPixelFormat pixelFormat = GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BUTT;
281
282 for (const auto &itr : surfaceBufferFmtToEffectFmt_) {
283 if (itr.second == formatType) {
284 pixelFormat = itr.first;
285 break;
286 }
287 }
288
289 return pixelFormat;
290 }
291
SwitchToPixelFormat(IEffectFormat formatType)292 PixelFormat CommonUtils::SwitchToPixelFormat(IEffectFormat formatType)
293 {
294 PixelFormat pixelFormat = PixelFormat::UNKNOWN;
295
296 for (const auto &itr : pixelFmtToEffectFmt_) {
297 if (itr.second == formatType) {
298 pixelFormat = itr.first;
299 break;
300 }
301 }
302
303 return pixelFormat;
304 }
305
SwitchToEffectBuffType(AllocatorType allocatorType)306 BufferType CommonUtils::SwitchToEffectBuffType(AllocatorType allocatorType)
307 {
308 BufferType bufferType = BufferType::DEFAULT;
309
310 auto itr = allocatorTypeToEffectBuffType_.find(allocatorType);
311 if (itr != allocatorTypeToEffectBuffType_.end()) {
312 bufferType = itr->second;
313 }
314
315 return bufferType;
316 }
317
UnlockPixelMap(const PixelMap * pixelMap)318 void CommonUtils::UnlockPixelMap(const PixelMap *pixelMap)
319 {
320 EFFECT_LOGI("UnlockPixelMap!");
321 }
322
ParseAnyAndAddToJson(const std::string & key,Plugin::Any & any,EffectJsonPtr & result)323 ErrorCode CommonUtils::ParseAnyAndAddToJson(const std::string &key, Plugin::Any &any, EffectJsonPtr &result)
324 {
325 CHECK_AND_RETURN_RET(ParseJson<float>(key, any, result) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
326 CHECK_AND_RETURN_RET(ParseJson<int32_t>(key, any, result) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
327 CHECK_AND_RETURN_RET(ParseJson<uint32_t>(key, any, result) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
328 #ifndef HST_ANY_WITH_NO_RTTI
329 EFFECT_LOGE("inner any type not support switch to json! type:%{public}s", any.Type().name());
330 #else
331 EFFECT_LOGE("inner any type not support switch to json! type:%{public}s", std::string(any.TypeName()).c_str());
332 #endif
333 return ErrorCode::ERR_ANY_CAST_TYPE_NOT_MATCH;
334 }
335
EndsWithJPG(const std::string & input)336 bool CommonUtils::EndsWithJPG(const std::string &input)
337 {
338 return StringHelp::EndsWithIgnoreCase(input, "jpg") || StringHelp::EndsWithIgnoreCase(input, "jpeg");
339 }
340
GetPixelsContext(std::shared_ptr<MemoryData> & memoryData,BufferType bufferType,void ** context)341 ErrorCode GetPixelsContext(std::shared_ptr<MemoryData> &memoryData, BufferType bufferType, void **context)
342 {
343 switch (bufferType) {
344 case BufferType::HEAP_MEMORY:
345 *context = nullptr;
346 break;
347 case BufferType::DMA_BUFFER: {
348 void *extra = memoryData->memoryInfo.extra;
349 auto surfaceBuffer = reinterpret_cast<SurfaceBuffer *>(extra);
350 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, ErrorCode::ERR_INVALID_SURFACE_BUFFER,
351 "DMA_BUFFER: extra info error!");
352 *context = surfaceBuffer;
353 break;
354 }
355 case BufferType::SHARED_MEMORY: {
356 void *extra = memoryData->memoryInfo.extra;
357 auto fd = static_cast<int *>(extra);
358 CHECK_AND_RETURN_RET_LOG(fd != nullptr, ErrorCode::ERR_INVALID_FD, "SHARED_MEMORY: extra info error!");
359 *context = fd;
360 break;
361 }
362 default:
363 EFFECT_LOGE("bufferType not support! bufferType=%{public}d", bufferType);
364 return ErrorCode::ERR_UNSUPPORTED_BUFFER_TYPE;
365 }
366 return ErrorCode::SUCCESS;
367 }
368
GetImagePropertyInt(const std::shared_ptr<ExifMetadata> & exifMetadata,const std::string & key,int32_t & value)369 int32_t GetImagePropertyInt(const std::shared_ptr<ExifMetadata> &exifMetadata, const std::string &key, int32_t &value)
370 {
371 std::string strValue;
372 int ret = exifMetadata->GetValue(key, strValue);
373 if (ret != 0) {
374 return ret;
375 }
376
377 std::from_chars_result res = std::from_chars(strValue.data(), strValue.data() + strValue.size(), value);
378 if (res.ec != std::errc()) {
379 return static_cast<int32_t>(ErrorCode::ERR_IMAGE_DATA);
380 }
381
382 return 0;
383 }
384
PrintImageExifInfo(const std::shared_ptr<ExifMetadata> & exifMetadata,const std::string & tag)385 void PrintImageExifInfo(const std::shared_ptr<ExifMetadata> &exifMetadata, const std::string &tag)
386 {
387 if (exifMetadata == nullptr) {
388 return;
389 }
390
391 int32_t width = 0;
392 GetImagePropertyInt(exifMetadata, IMAGE_WIDTH, width);
393 int32_t length = 0;
394 GetImagePropertyInt(exifMetadata, IMAGE_LENGTH, length);
395 std::string dateTime;
396 exifMetadata->GetValue(DATE_TIME, dateTime);
397 int32_t xDimension = 0;
398 GetImagePropertyInt(exifMetadata, PIXEL_X_DIMENSION, xDimension);
399 int32_t yDimension = 0;
400 GetImagePropertyInt(exifMetadata, PIXEL_Y_DIMENSION, yDimension);
401
402 EFFECT_LOGD("%{public}s: width=%{public}d, length=%{public}d, dateTime=%{public}s, xDimension=%{public}d, "
403 "yDimension=%{public}d", tag.c_str(), width, length, dateTime.c_str(), xDimension, yDimension);
404 }
405
UpdateExifDataTime(const std::shared_ptr<ExifMetadata> & exifMetadata)406 void UpdateExifDataTime(const std::shared_ptr<ExifMetadata> &exifMetadata)
407 {
408 CHECK_AND_RETURN_LOG(exifMetadata != nullptr, "UpdateExifDataTime: exifMetadata is null!");
409
410 std::string dateTime;
411 if (exifMetadata->GetValue(DATE_TIME, dateTime) != 0 || dateTime.empty()) {
412 return;
413 }
414
415 time_t now = time(nullptr);
416 CHECK_AND_RETURN_LOG(now > 0, "UpdateExifDateTime: time fail!");
417
418 struct tm *locTime = localtime(&now);
419 CHECK_AND_RETURN_LOG(locTime != nullptr, "UpdateExifDateTime: localtime fail!");
420
421 char tempTime[TIME_MAX];
422 auto size = strftime(tempTime, sizeof(tempTime), "%Y:%m:%d %H:%M:%S", locTime);
423 CHECK_AND_RETURN_LOG(size > 0, "UpdateExifDateTime: strftime fail!");
424
425 std::string currentTime = std::string(tempTime, size);
426 bool res = exifMetadata->SetValue(DATE_TIME, currentTime);
427 CHECK_AND_RETURN_LOG(res, "UpdateExifDataTime: setValue fail!");
428 }
429
UpdateImageExifDateTime(PixelMap * pixelMap)430 void CommonUtils::UpdateImageExifDateTime(PixelMap *pixelMap)
431 {
432 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "UpdateImageExifDateTime: pixelMap is null!");
433
434 UpdateExifDataTime(pixelMap->GetExifMetadata());
435 }
436
UpdateImageExifDateTime(Picture * picture)437 void CommonUtils::UpdateImageExifDateTime(Picture *picture)
438 {
439 CHECK_AND_RETURN_LOG(picture != nullptr, "UpdateImageExifDateTime: picture is null!");
440
441 UpdateExifDataTime(picture->GetExifMetadata());
442 }
443
UpdateExifMetadata(const std::shared_ptr<ExifMetadata> & exifMetadata,PixelMap * pixelMap)444 void UpdateExifMetadata(const std::shared_ptr<ExifMetadata> &exifMetadata, PixelMap *pixelMap)
445 {
446 if (exifMetadata == nullptr) {
447 EFFECT_LOGI("UpdateExifMetadata: no exif info.");
448 return;
449 }
450
451 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "UpdateExifMetadata: pixelMap is null");
452 PrintImageExifInfo(exifMetadata, "UpdateImageExifInfo::update before");
453
454 // Set Width
455 int32_t width = 0;
456 if (GetImagePropertyInt(exifMetadata, IMAGE_WIDTH, width) == 0 && pixelMap->GetWidth() != width) {
457 exifMetadata->SetValue(IMAGE_WIDTH, std::to_string(pixelMap->GetWidth()));
458 }
459
460 // Set Length
461 int32_t length = 0;
462 if (GetImagePropertyInt(exifMetadata, IMAGE_LENGTH, width) == 0 && pixelMap->GetHeight() != length) {
463 exifMetadata->SetValue(IMAGE_LENGTH, std::to_string(pixelMap->GetHeight()));
464 }
465
466 // Set DateTime
467 UpdateExifDataTime(exifMetadata);
468
469 // Set PixelXDimension
470 int32_t xDimension = 0;
471 if (GetImagePropertyInt(exifMetadata, PIXEL_X_DIMENSION, xDimension) == 0 && pixelMap->GetWidth() != xDimension) {
472 exifMetadata->SetValue(PIXEL_X_DIMENSION, std::to_string(pixelMap->GetWidth()));
473 }
474
475 // Set PixelYDimension
476 int32_t yDimension = 0;
477 if (GetImagePropertyInt(exifMetadata, PIXEL_Y_DIMENSION, xDimension) == 0 && pixelMap->GetHeight() != yDimension) {
478 exifMetadata->SetValue(PIXEL_Y_DIMENSION, std::to_string(pixelMap->GetHeight()));
479 }
480
481 PrintImageExifInfo(exifMetadata, "UpdateImageExifInfo::update after");
482 }
483
UpdateImageExifInfo(PixelMap * pixelMap)484 void CommonUtils::UpdateImageExifInfo(PixelMap *pixelMap)
485 {
486 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "UpdateImageExifInfo: pixelMap is null!");
487
488 UpdateExifMetadata(pixelMap->GetExifMetadata(), pixelMap);
489 }
490
UpdateImageExifInfo(Picture * picture)491 void CommonUtils::UpdateImageExifInfo(Picture *picture)
492 {
493 CHECK_AND_RETURN_LOG(picture != nullptr, "UpdateImageExifInfo: picture is null!");
494
495 UpdateExifMetadata(picture->GetExifMetadata(), picture->GetMainPixel().get());
496 }
497
ParsePicture(Picture * picture,std::shared_ptr<EffectBuffer> & effectBuffer)498 ErrorCode CommonUtils::ParsePicture(Picture *picture, std::shared_ptr<EffectBuffer> &effectBuffer)
499 {
500 EFFECT_LOGI("CommonUtils::ParsePicture enter.");
501 CHECK_AND_RETURN_RET_LOG(picture != nullptr, ErrorCode::ERR_INPUT_NULL, "ParsePicture: picture is null!");
502
503 std::shared_ptr<PixelMap> pixelMap = picture->GetMainPixel();
504 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "ParsePicture: main pixel is null!");
505 ErrorCode errorCode = CommonUtils::LockPixelMap(pixelMap.get(), effectBuffer);
506 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode,
507 "ParsePicture: parse main pixel fail! errorCode=%{public}d", errorCode);
508
509 effectBuffer->bufferInfo_->pixelmapType_ = EffectPixelmapType::PRIMARY;
510 effectBuffer->bufferInfo_->bufferType_ = effectBuffer->extraInfo_->bufferType;
511 effectBuffer->bufferInfo_->addr_ = effectBuffer->buffer_;
512 effectBuffer->extraInfo_->dataType = DataType::PICTURE;
513 effectBuffer->extraInfo_->picture = picture;
514
515 std::shared_ptr<PixelMap> gainMap = picture->GetGainmapPixelMap();
516 if (gainMap == nullptr) {
517 EFFECT_LOGD("CommonUtils::ParsePicture not contain gainmap!");
518 return ErrorCode::SUCCESS;
519 }
520
521 EFFECT_LOGD("CommonUtils::ParsePicture contain gainmap!");
522 std::shared_ptr<EffectBuffer> gainMapEffectBuffer;
523 errorCode = CommonUtils::LockPixelMap(gainMap.get(), gainMapEffectBuffer);
524 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode,
525 "ParsePicture: parse gainmap fail! errorCode=%{public}d", errorCode);
526
527 gainMapEffectBuffer->bufferInfo_->pixelmapType_ = EffectPixelmapType::GAINMAP;
528 gainMapEffectBuffer->bufferInfo_->bufferType_ = gainMapEffectBuffer->extraInfo_->bufferType;
529 gainMapEffectBuffer->bufferInfo_->addr_ = gainMapEffectBuffer->buffer_;
530
531 effectBuffer->auxiliaryBufferInfos =
532 std::make_shared<std::unordered_map<EffectPixelmapType, std::shared_ptr<BufferInfo>>>();
533 effectBuffer->auxiliaryBufferInfos->emplace(EffectPixelmapType::GAINMAP, gainMapEffectBuffer->bufferInfo_);
534
535 return ErrorCode::SUCCESS;
536 }
537
ModifyPixelMapPropertyInner(std::shared_ptr<MemoryData> & memoryData,PixelMap * pixelMap,AllocatorType & allocatorType,bool isUpdateExif)538 ErrorCode ModifyPixelMapPropertyInner(std::shared_ptr<MemoryData> &memoryData, PixelMap *pixelMap,
539 AllocatorType &allocatorType, bool isUpdateExif)
540 {
541 void *context = nullptr;
542 const MemoryInfo &memoryInfo = memoryData->memoryInfo;
543 ErrorCode res = GetPixelsContext(memoryData, memoryInfo.bufferType, &context);
544 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "get pixels context fail! res=%{public}d", res);
545
546 // not need to release the origin buffer in pixelMap, SetPixelsAddr will release it.
547 pixelMap->SetPixelsAddr(memoryData->data, context, memoryInfo.bufferInfo.len_, allocatorType, nullptr);
548
549 ImageInfo imageInfo;
550 pixelMap->GetImageInfo(imageInfo);
551 imageInfo.size.width = static_cast<int32_t>(memoryInfo.bufferInfo.width_);
552 imageInfo.size.height = static_cast<int32_t>(memoryInfo.bufferInfo.height_);
553 imageInfo.pixelFormat = CommonUtils::SwitchToPixelFormat(memoryInfo.bufferInfo.formatType_);
554 uint32_t result = pixelMap->SetImageInfo(imageInfo, true);
555 EFFECT_LOGI("ModifyPixelMapPropertyInner: SetImageInfo width=%{public}d, height=%{public}d, result: %{public}d",
556 imageInfo.size.width, imageInfo.size.height, result);
557 CHECK_AND_RETURN_RET_LOG(result == 0, ErrorCode::ERR_SET_IMAGE_INFO_FAIL,
558 "ModifyPixelMapPropertyInner: exec SetImageInfo fail! result=%{public}d", result);
559
560 // update rowStride
561 pixelMap->SetRowStride(memoryInfo.bufferInfo.rowStride_);
562
563 if (isUpdateExif) {
564 // update exif
565 CommonUtils::UpdateImageExifInfo(pixelMap);
566 }
567
568 EffectColorSpace colorSpace = memoryInfo.bufferInfo.colorSpace_;
569 if (colorSpace != EffectColorSpace::DEFAULT) {
570 OHOS::ColorManager::ColorSpace grColorSpace(ColorSpaceHelper::ConvertToColorSpaceName(colorSpace));
571 pixelMap->InnerSetColorSpace(grColorSpace);
572 }
573
574 // update colorspace if need
575 if (memoryInfo.bufferType == BufferType::DMA_BUFFER) {
576 res = ColorSpaceHelper::UpdateMetadata(static_cast<SurfaceBuffer *>(memoryInfo.extra),
577 memoryInfo.bufferInfo.colorSpace_);
578 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res,
579 "ModifyPixelMapPropertyInner: UpdateMetadata fail! res=%{public}d", res);
580 }
581
582 return ErrorCode::SUCCESS;
583 }
584
ModifyPixelMapProperty(PixelMap * pixelMap,const std::shared_ptr<EffectBuffer> & buffer,const std::shared_ptr<EffectMemoryManager> & memoryManager,bool isUpdateExif)585 ErrorCode CommonUtils::ModifyPixelMapProperty(PixelMap *pixelMap, const std::shared_ptr<EffectBuffer> &buffer,
586 const std::shared_ptr<EffectMemoryManager> &memoryManager, bool isUpdateExif)
587 {
588 EFFECT_LOGI("ModifyPixelMapProperty enter!");
589 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "pixel map is null");
590 AllocatorType allocatorType = pixelMap->GetAllocatorType();
591 BufferType bufferType = SwitchToEffectBuffType(allocatorType);
592 EFFECT_LOGD("ModifyPixelMapProperty: allocatorType=%{public}d, bufferType=%{public}d", allocatorType, bufferType);
593 std::shared_ptr<Memory> allocMemory = memoryManager->GetAllocMemoryByAddr(buffer->buffer_);
594 std::shared_ptr<MemoryData> memoryData;
595 if (allocMemory != nullptr && allocMemory->memoryData_->memoryInfo.bufferType == bufferType) {
596 EFFECT_LOGD("ModifyPixelMapProperty reuse allocated memory. addr=%{public}p", buffer->buffer_);
597 allocMemory->memoryData_->memoryInfo.isAutoRelease = false;
598 memoryData = allocMemory->memoryData_;
599 } else {
600 EFFECT_LOGD("ModifyPixelMapProperty alloc memory.");
601 std::unique_ptr<AbsMemory> memory = EffectMemory::CreateMemory(bufferType);
602 CHECK_AND_RETURN_RET_LOG(memory != nullptr, ErrorCode::ERR_CREATE_MEMORY_FAIL,
603 "memory create fail! allocatorType=%{public}d", allocatorType);
604
605 MemoryInfo memoryInfo = {
606 .isAutoRelease = false,
607 .bufferInfo = *buffer->bufferInfo_,
608 .extra = pixelMap->GetFd()
609 };
610 if (bufferType != BufferType::DMA_BUFFER) {
611 memoryInfo.bufferInfo.len_ = FormatHelper::CalculateSize(buffer->bufferInfo_->width_,
612 buffer->bufferInfo_->height_, buffer->bufferInfo_->formatType_);
613 }
614 memoryData = memory->Alloc(memoryInfo);
615 CHECK_AND_RETURN_RET_LOG(memoryData != nullptr, ErrorCode::ERR_ALLOC_MEMORY_FAIL, "Alloc fail!");
616 MemcpyHelper::CopyData(buffer.get(), memoryData.get());
617 }
618
619 return ModifyPixelMapPropertyInner(memoryData, pixelMap, allocatorType, isUpdateExif);
620 }
621
ModifyPixelMapPropertyForTexture(PixelMap * pixelMap,const std::shared_ptr<EffectBuffer> & buffer,const std::shared_ptr<EffectContext> & context,bool isUpdateExif)622 ErrorCode CommonUtils::ModifyPixelMapPropertyForTexture(PixelMap *pixelMap, const std::shared_ptr<EffectBuffer> &buffer,
623 const std::shared_ptr<EffectContext> &context, bool isUpdateExif)
624 {
625 EFFECT_LOGI("ModifyPixelMapPropertyForTexture enter!");
626 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "pixel map is null");
627 AllocatorType allocatorType = pixelMap->GetAllocatorType();
628 BufferType bufferType = SwitchToEffectBuffType(allocatorType);
629 EFFECT_LOGD("ModifyPixelMapProperty: allocatorType=%{public}d, bufferType=%{public}d", allocatorType, bufferType);
630 std::unique_ptr<AbsMemory> memory = EffectMemory::CreateMemory(bufferType);
631 CHECK_AND_RETURN_RET_LOG(memory != nullptr, ErrorCode::ERR_CREATE_MEMORY_FAIL,
632 "memory create fail! allocatorType=%{public}d", allocatorType);
633
634 MemoryInfo memoryInfo = {
635 .isAutoRelease = false,
636 .bufferInfo = *buffer->bufferInfo_,
637 .extra = pixelMap->GetFd()
638 };
639 std::shared_ptr<MemoryData> memoryData = memory->Alloc(memoryInfo);
640 CHECK_AND_RETURN_RET_LOG(memoryData != nullptr, ErrorCode::ERR_ALLOC_MEMORY_FAIL, "Alloc fail!");
641 context->renderEnvironment_->ReadPixelsFromTex(buffer->tex, memoryData->data, buffer->bufferInfo_->width_,
642 buffer->bufferInfo_->height_, memoryData->memoryInfo.bufferInfo.rowStride_ / RGBA_BYTES_PER_PIXEL);
643
644 return ModifyPixelMapPropertyInner(memoryData, pixelMap, allocatorType, isUpdateExif);
645 }
646 } // namespace Effect
647 } // namespace Media
648 } // namespace OHOS