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