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_utils.h"
17
18 #include <sys/stat.h>
19 #include <cerrno>
20 #include <charconv>
21 #include <climits>
22 #include <cmath>
23 #include <cstdint>
24 #include <cstdlib>
25 #include <string>
26 #include <fstream>
27 #include <sstream>
28 #include <chrono>
29
30 #include "__config"
31 #include "image_log.h"
32 #include "ios"
33 #include "istream"
34 #include "media_errors.h"
35 #include "new"
36 #include "plugin_server.h"
37 #include "singleton.h"
38 #include "string"
39 #include "type_traits"
40 #include "vector"
41 #include "image_trace.h"
42 #include "hitrace_meter.h"
43 #include "image_system_properties.h"
44 #include "image/abs_image_decoder.h"
45 #include "pixel_map.h"
46 #ifdef IOS_PLATFORM
47 #include <sys/syscall.h>
48 #endif
49 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
50 #include "surface_type.h"
51 #include "surface_buffer.h"
52 #include "bundle_mgr_interface.h"
53 #include "iservice_registry.h"
54 #include "ipc_skeleton.h"
55 #include "system_ability_definition.h"
56 #include "os_account_manager.h"
57 #else
58 #include "refbase.h"
59 #endif
60
61 #undef LOG_DOMAIN
62 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
63
64 #undef LOG_TAG
65 #define LOG_TAG "imageUtils"
66
67 namespace OHOS {
68 namespace Media {
69 using namespace std;
70 using namespace MultimediaPlugin;
71
72 constexpr int32_t ALPHA8_BYTES = 1;
73 constexpr int32_t RGB565_BYTES = 2;
74 constexpr int32_t RGB888_BYTES = 3;
75 constexpr int32_t ARGB8888_BYTES = 4;
76 constexpr int32_t RGBA_F16_BYTES = 8;
77 constexpr int32_t NV21_BYTES = 2; // Each pixel is sorted on 3/2 bytes.
78 constexpr uint8_t MOVE_BITS_8 = 8;
79 constexpr uint8_t MOVE_BITS_16 = 16;
80 constexpr uint8_t MOVE_BITS_24 = 24;
81 constexpr int32_t NV21P010_BYTES = 3;
82 constexpr int32_t ASTC_4X4_BYTES = 1;
83 constexpr int32_t ASTC_4X4_BLOCK = 4;
84 constexpr int32_t ASTC_6X6_BLOCK = 6;
85 constexpr int32_t ASTC_8X8_BLOCK = 8;
86 constexpr int32_t ASTC_BLOCK_SIZE = 16;
87 constexpr int32_t ASTC_HEADER_SIZE = 16;
88 constexpr uint8_t FILL_NUMBER = 3;
89 constexpr uint8_t ALIGN_NUMBER = 4;
90 constexpr int32_t FAULT_API_VERSION = -1;
91 constexpr int32_t BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401;
92 constexpr float EPSILON = 1e-6;
93 constexpr int MAX_DIMENSION = INT32_MAX >> 2;
94 constexpr int32_t DMA_SIZE = 512 * 512;
95 static bool g_pluginRegistered = false;
96 static const uint8_t NUM_0 = 0;
97 static const uint8_t NUM_1 = 1;
98 static const uint8_t NUM_2 = 2;
99 static const uint8_t NUM_3 = 3;
100 static const uint8_t NUM_4 = 4;
101 static const uint8_t NUM_5 = 5;
102 static const uint8_t NUM_6 = 6;
103 static const uint8_t NUM_7 = 7;
104 static const string FILE_DIR_IN_THE_SANDBOX = "/data/storage/el2/base/files/";
105
GetFileSize(const string & pathName,size_t & size)106 bool ImageUtils::GetFileSize(const string &pathName, size_t &size)
107 {
108 if (pathName.empty()) {
109 IMAGE_LOGE("[ImageUtil]input parameter exception.");
110 return false;
111 }
112 struct stat statbuf;
113 int ret = stat(pathName.c_str(), &statbuf);
114 if (ret != 0) {
115 IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d, errno:%{public}d.", ret, errno);
116 return false;
117 }
118 size = statbuf.st_size;
119 return true;
120 }
121
GetFileSize(const int fd,size_t & size)122 bool ImageUtils::GetFileSize(const int fd, size_t &size)
123 {
124 struct stat statbuf;
125
126 if (fd < 0) {
127 return false;
128 }
129
130 int ret = fstat(fd, &statbuf);
131 if (ret != 0) {
132 IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d, errno:%{public}d.", ret, errno);
133 return false;
134 }
135 size = statbuf.st_size;
136 return true;
137 }
138
GetInputStreamSize(istream & inputStream,size_t & size)139 bool ImageUtils::GetInputStreamSize(istream &inputStream, size_t &size)
140 {
141 if (inputStream.rdbuf() == nullptr) {
142 IMAGE_LOGE("[ImageUtil]input parameter exception.");
143 return false;
144 }
145 size_t original = inputStream.tellg();
146 inputStream.seekg(0, ios_base::end);
147 size = inputStream.tellg();
148 inputStream.seekg(original);
149 return true;
150 }
151
GetPixelBytes(const PixelFormat & pixelFormat)152 int32_t ImageUtils::GetPixelBytes(const PixelFormat &pixelFormat)
153 {
154 int pixelBytes = 0;
155 switch (pixelFormat) {
156 case PixelFormat::ARGB_8888:
157 case PixelFormat::BGRA_8888:
158 case PixelFormat::RGBA_8888:
159 case PixelFormat::RGBA_1010102:
160 case PixelFormat::CMYK:
161 pixelBytes = ARGB8888_BYTES;
162 break;
163 case PixelFormat::ALPHA_8:
164 pixelBytes = ALPHA8_BYTES;
165 break;
166 case PixelFormat::RGB_888:
167 pixelBytes = RGB888_BYTES;
168 break;
169 case PixelFormat::RGB_565:
170 pixelBytes = RGB565_BYTES;
171 break;
172 case PixelFormat::RGBA_F16:
173 case PixelFormat::RGBA_U16:
174 pixelBytes = RGBA_F16_BYTES;
175 break;
176 case PixelFormat::NV21:
177 case PixelFormat::NV12:
178 pixelBytes = NV21_BYTES; // perl pixel 1.5 Bytes but return int so return 2
179 break;
180 case PixelFormat::ASTC_4x4:
181 case PixelFormat::ASTC_6x6:
182 case PixelFormat::ASTC_8x8:
183 pixelBytes = ASTC_4X4_BYTES;
184 break;
185 case PixelFormat::YCBCR_P010:
186 case PixelFormat::YCRCB_P010:
187 pixelBytes = NV21P010_BYTES;
188 break;
189 default:
190 IMAGE_LOGE("[ImageUtil]get pixel bytes failed, pixelFormat:%{public}d.",
191 static_cast<int32_t>(pixelFormat));
192 break;
193 }
194 return pixelBytes;
195 }
196
GetRowDataSizeByPixelFormat(const int32_t & width,const PixelFormat & format)197 int32_t ImageUtils::GetRowDataSizeByPixelFormat(const int32_t &width, const PixelFormat &format)
198 {
199 uint64_t uWidth = static_cast<uint64_t>(width);
200 uint64_t pixelBytes = static_cast<uint64_t>(GetPixelBytes(format));
201 uint64_t rowDataSize = 0;
202 switch (format) {
203 case PixelFormat::ALPHA_8:
204 rowDataSize = pixelBytes * ((uWidth + FILL_NUMBER) / ALIGN_NUMBER * ALIGN_NUMBER);
205 break;
206 case PixelFormat::ASTC_4x4:
207 rowDataSize = pixelBytes * (((uWidth + NUM_3) >> NUM_2) << NUM_2);
208 break;
209 case PixelFormat::ASTC_6x6:
210 rowDataSize = pixelBytes * (((uWidth + NUM_5) / NUM_6) * NUM_6);
211 break;
212 case PixelFormat::ASTC_8x8:
213 rowDataSize = pixelBytes * (((uWidth + NUM_7) >> NUM_3) << NUM_3);
214 break;
215 default:
216 rowDataSize = pixelBytes * uWidth;
217 }
218 if (rowDataSize > INT32_MAX) {
219 IMAGE_LOGE("GetRowDataSizeByPixelFormat failed: rowDataSize overflowed");
220 return -1;
221 }
222 return static_cast<int32_t>(rowDataSize);
223 }
224
RegisterPluginServer()225 uint32_t ImageUtils::RegisterPluginServer()
226 {
227 #ifdef _WIN32
228 vector<string> pluginPaths = { "" };
229 #elif defined(_APPLE)
230 vector<string> pluginPaths = { "./" };
231 #elif defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
232 vector<string> pluginPaths = {};
233 #else
234 vector<string> pluginPaths = { "/system/etc/multimediaplugin/image" };
235 #endif
236 PluginServer &pluginServer = DelayedRefSingleton<PluginServer>::GetInstance();
237 uint32_t result = pluginServer.Register(std::move(pluginPaths));
238 if (result != SUCCESS) {
239 IMAGE_LOGE("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
240 } else {
241 g_pluginRegistered = true;
242 IMAGE_LOGD("[ImageUtil]success to register plugin server");
243 }
244 return result;
245 }
246
GetPluginServer()247 PluginServer& ImageUtils::GetPluginServer()
248 {
249 if (!g_pluginRegistered) {
250 uint32_t result = RegisterPluginServer();
251 if (result != SUCCESS) {
252 IMAGE_LOGI("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
253 }
254 }
255 return DelayedRefSingleton<PluginServer>::GetInstance();
256 }
257
PathToRealPath(const string & path,string & realPath)258 bool ImageUtils::PathToRealPath(const string &path, string &realPath)
259 {
260 if (path.empty()) {
261 IMAGE_LOGE("path is empty!");
262 return false;
263 }
264
265 if ((path.length() >= PATH_MAX)) {
266 IMAGE_LOGE("path len is error, the len is: [%{public}lu]", static_cast<unsigned long>(path.length()));
267 return false;
268 }
269
270 char tmpPath[PATH_MAX] = { 0 };
271
272 #ifdef _WIN32
273 if (_fullpath(tmpPath, path.c_str(), path.length()) == nullptr) {
274 IMAGE_LOGW("path to _fullpath error");
275 }
276 #else
277 if (realpath(path.c_str(), tmpPath) == nullptr) {
278 IMAGE_LOGE("path to realpath is nullptr");
279 return false;
280 }
281 #endif
282
283 realPath = tmpPath;
284 return true;
285 }
286
FloatCompareZero(float src)287 bool ImageUtils::FloatCompareZero(float src)
288 {
289 return fabs(src - 0) < EPSILON;
290 }
291
GetValidAlphaTypeByFormat(const AlphaType & dstType,const PixelFormat & format)292 AlphaType ImageUtils::GetValidAlphaTypeByFormat(const AlphaType &dstType, const PixelFormat &format)
293 {
294 switch (format) {
295 case PixelFormat::RGBA_8888:
296 case PixelFormat::BGRA_8888:
297 case PixelFormat::ARGB_8888:
298 case PixelFormat::RGBA_1010102:
299 case PixelFormat::RGBA_F16: {
300 break;
301 }
302 case PixelFormat::ALPHA_8: {
303 if (dstType != AlphaType::IMAGE_ALPHA_TYPE_PREMUL) {
304 return AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
305 }
306 break;
307 }
308 case PixelFormat::RGB_888:
309 case PixelFormat::RGB_565: {
310 if (dstType != AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
311 return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
312 }
313 break;
314 }
315 case PixelFormat::NV21:
316 case PixelFormat::NV12:
317 case PixelFormat::YCBCR_P010:
318 case PixelFormat::YCRCB_P010: {
319 if (dstType != AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
320 return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
321 }
322 break;
323 }
324 case PixelFormat::CMYK:
325 default: {
326 IMAGE_LOGE("GetValidAlphaTypeByFormat unsupport the format(%{public}d).", format);
327 return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
328 }
329 }
330 return dstType;
331 }
332
GetPixelMapAllocatorType(const Size & size,const PixelFormat & format,bool useDMA)333 AllocatorType ImageUtils::GetPixelMapAllocatorType(const Size &size, const PixelFormat &format, bool useDMA)
334 {
335 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
336 return useDMA && (format == PixelFormat::RGBA_8888 || (format == PixelFormat::RGBA_1010102 ||
337 format == PixelFormat::YCRCB_P010 ||
338 format == PixelFormat::YCBCR_P010)) &&
339 size.width * size.height >= DMA_SIZE ?
340 AllocatorType::DMA_ALLOC : AllocatorType::SHARE_MEM_ALLOC;
341 #else
342 return AllocatorType::HEAP_ALLOC;
343 #endif
344 }
345
IsValidImageInfo(const ImageInfo & info)346 bool ImageUtils::IsValidImageInfo(const ImageInfo &info)
347 {
348 if (info.size.width <= 0 || info.size.height <= 0 || info.size.width > MAX_DIMENSION ||
349 info.size.height > MAX_DIMENSION) {
350 IMAGE_LOGE("width(%{public}d) or height(%{public}d) is invalid.", info.size.width, info.size.height);
351 return false;
352 }
353 if (info.pixelFormat == PixelFormat::UNKNOWN || info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
354 IMAGE_LOGE("check pixelformat and alphatype is invalid.");
355 return false;
356 }
357 return true;
358 }
359
IsValidAuxiliaryInfo(const std::shared_ptr<PixelMap> & pixelMap,const AuxiliaryPictureInfo & info)360 bool ImageUtils::IsValidAuxiliaryInfo(const std::shared_ptr<PixelMap> &pixelMap, const AuxiliaryPictureInfo &info)
361 {
362 int32_t rowSize = ImageUtils::GetRowDataSizeByPixelFormat(info.size.width, info.pixelFormat);
363 if (rowSize <= 0 || info.size.height <= 0 || rowSize > std::numeric_limits<int32_t>::max() / info.size.height) {
364 IMAGE_LOGE("%{public}s rowSize: %{public}d, height: %{public}d may overflowed",
365 __func__, rowSize, info.size.height);
366 return false;
367 }
368 uint32_t infoSize = static_cast<uint32_t>(rowSize * info.size.height);
369 uint32_t pixelsSize = pixelMap->GetCapacity();
370 if (infoSize > pixelsSize) {
371 IMAGE_LOGE("%{public}s invalid infoSize: %{public}u, pixelsSize: %{public}u", __func__, infoSize, pixelsSize);
372 return false;
373 }
374 return true;
375 }
376
IsAstc(PixelFormat format)377 bool ImageUtils::IsAstc(PixelFormat format)
378 {
379 return format == PixelFormat::ASTC_4x4 || format == PixelFormat::ASTC_6x6 || format == PixelFormat::ASTC_8x8;
380 }
381
CheckMulOverflow(int32_t width,int32_t bytesPerPixel)382 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t bytesPerPixel)
383 {
384 if (width == 0 || bytesPerPixel == 0) {
385 IMAGE_LOGE("param is 0");
386 return true;
387 }
388 int32_t rowSize = width * bytesPerPixel;
389 if ((rowSize / width) != bytesPerPixel) {
390 IMAGE_LOGE("width * bytesPerPixel overflow!");
391 return true;
392 }
393 return false;
394 }
395
CheckMulOverflow(int32_t width,int32_t height,int32_t bytesPerPixel)396 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t height, int32_t bytesPerPixel)
397 {
398 if (width == 0 || height == 0 || bytesPerPixel == 0) {
399 IMAGE_LOGE("param is 0");
400 return true;
401 }
402 int32_t rectSize = width * height;
403 if ((rectSize / width) != height) {
404 IMAGE_LOGE("width * height overflow!");
405 return true;
406 }
407 int32_t bufferSize = rectSize * bytesPerPixel;
408 if ((bufferSize / bytesPerPixel) != rectSize) {
409 IMAGE_LOGE("bytesPerPixel overflow!");
410 return true;
411 }
412 return false;
413 }
414
ReversePixels(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)415 static void ReversePixels(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
416 {
417 if (byteCount % NUM_4 != NUM_0) {
418 IMAGE_LOGE("Pixel count must multiple of 4.");
419 return;
420 }
421 uint8_t *src = srcPixels;
422 uint8_t *dst = dstPixels;
423 for (uint32_t i = NUM_0 ; i < byteCount; i += NUM_4) {
424 // 0-B 1-G 2-R 3-A
425 dst[NUM_0] = src[NUM_3];
426 dst[NUM_1] = src[NUM_2];
427 dst[NUM_2] = src[NUM_1];
428 dst[NUM_3] = src[NUM_0];
429 src += NUM_4;
430 dst += NUM_4;
431 }
432 }
433
BGRAToARGB(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)434 void ImageUtils::BGRAToARGB(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
435 {
436 ImageTrace imageTrace("BGRAToARGB");
437 ReversePixels(srcPixels, dstPixels, byteCount);
438 }
439
ARGBToBGRA(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)440 void ImageUtils::ARGBToBGRA(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
441 {
442 ReversePixels(srcPixels, dstPixels, byteCount);
443 }
444
SurfaceBuffer_Reference(void * buffer)445 int32_t ImageUtils::SurfaceBuffer_Reference(void* buffer)
446 {
447 if (buffer == nullptr) {
448 IMAGE_LOGE("parameter error, please check input parameter");
449 return ERR_SURFACEBUFFER_REFERENCE_FAILED;
450 }
451 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
452 ref->IncStrongRef(ref);
453 return SUCCESS;
454 }
455
SurfaceBuffer_Unreference(void * buffer)456 int32_t ImageUtils::SurfaceBuffer_Unreference(void* buffer)
457 {
458 if (buffer == nullptr) {
459 IMAGE_LOGE("parameter error, please check input parameter");
460 return ERR_SURFACEBUFFER_UNREFERENCE_FAILED;
461 }
462 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
463 ref->DecStrongRef(ref);
464 return SUCCESS;
465 }
466
DumpPixelMap(PixelMap * pixelMap,std::string customFileName,uint64_t imageId)467 void ImageUtils::DumpPixelMap(PixelMap* pixelMap, std::string customFileName, uint64_t imageId)
468 {
469 IMAGE_LOGI("ImageUtils::DumpPixelMap start");
470 std::string fileName = FILE_DIR_IN_THE_SANDBOX + GetLocalTime() + customFileName + std::to_string(imageId) +
471 GetPixelMapName(pixelMap) + ".dat";
472 int32_t totalSize = pixelMap->GetRowStride() * pixelMap->GetHeight();
473 PixelFormat pixelFormat = pixelMap->GetPixelFormat();
474 if (pixelFormat == PixelFormat::NV12 || pixelFormat == PixelFormat::NV21 ||
475 pixelFormat == PixelFormat::YCBCR_P010 || pixelFormat == PixelFormat::YCRCB_P010) {
476 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
477 if (pixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
478 auto sbBuffer = reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
479 if (!sbBuffer) {
480 return;
481 }
482 totalSize = static_cast<int32_t>(sbBuffer->GetSize());
483 } else {
484 totalSize = static_cast<int32_t>(pixelMap->GetCapacity());
485 }
486 #else
487 totalSize = static_cast<int32_t>(pixelMap->GetCapacity());
488 #endif
489 IMAGE_LOGI("ImageUtils::DumpPixelMap YUV420 totalSize is %{public}d", totalSize);
490 }
491 if (SUCCESS != SaveDataToFile(fileName, reinterpret_cast<const char*>(pixelMap->GetPixels()), totalSize)) {
492 IMAGE_LOGI("ImageUtils::DumpPixelMap failed");
493 return;
494 }
495 IMAGE_LOGI("ImageUtils::DumpPixelMap success, path = %{public}s", fileName.c_str());
496 }
497
DumpPixelMapIfDumpEnabled(std::unique_ptr<PixelMap> & pixelMap,uint64_t imageId)498 void ImageUtils::DumpPixelMapIfDumpEnabled(std::unique_ptr<PixelMap>& pixelMap, uint64_t imageId)
499 {
500 if (!ImageSystemProperties::GetDumpImageEnabled()) {
501 return;
502 }
503 if (pixelMap == nullptr) {
504 IMAGE_LOGI("ImageUtils::DumpPixelMapIfDumpEnabled pixelMap is null");
505 return;
506 }
507 DumpPixelMap(pixelMap.get(), "_imageId", imageId);
508 }
509
DumpPixelMapBeforeEncode(PixelMap & pixelMap)510 void ImageUtils::DumpPixelMapBeforeEncode(PixelMap& pixelMap)
511 {
512 if (!ImageSystemProperties::GetDumpImageEnabled()) {
513 return;
514 }
515 DumpPixelMap(&pixelMap, "_beforeEncode");
516 }
517
DumpDataIfDumpEnabled(const char * data,const size_t & totalSize,const std::string & fileSuffix,uint64_t imageId)518 void ImageUtils::DumpDataIfDumpEnabled(const char* data, const size_t& totalSize,
519 const std::string& fileSuffix, uint64_t imageId)
520 {
521 if (!ImageSystemProperties::GetDumpImageEnabled()) {
522 return;
523 }
524 std::string fileName = FILE_DIR_IN_THE_SANDBOX + GetLocalTime() + "_imageId" + std::to_string(imageId) +
525 "_data_total" + std::to_string(totalSize) + "." + fileSuffix;
526 if (SUCCESS != SaveDataToFile(fileName, data, totalSize)) {
527 IMAGE_LOGI("ImageUtils::DumpDataIfDumpEnabled failed");
528 return;
529 }
530 IMAGE_LOGI("ImageUtils::DumpDataIfDumpEnabled success, path = %{public}s", fileName.c_str());
531 }
532
GetNowTimeMilliSeconds()533 uint64_t ImageUtils::GetNowTimeMilliSeconds()
534 {
535 auto now = std::chrono::system_clock::now();
536 return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
537 }
538
GetNowTimeMicroSeconds()539 uint64_t ImageUtils::GetNowTimeMicroSeconds()
540 {
541 auto now = std::chrono::system_clock::now();
542 return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
543 }
544
GetCurrentProcessName()545 std::string ImageUtils::GetCurrentProcessName()
546 {
547 std::string processName;
548 std::ifstream cmdlineFile("/proc/self/cmdline");
549 if (cmdlineFile.is_open()) {
550 std::ostringstream oss;
551 oss << cmdlineFile.rdbuf();
552 cmdlineFile.close();
553
554 //Extrace process name from the command line
555 std::string cmdline = oss.str();
556 size_t pos = cmdline.find_first_of('\0');
557 if (pos != std::string::npos) {
558 processName = cmdline.substr(0, pos);
559 }
560 }
561 return processName;
562 }
563
SaveDataToFile(const std::string & fileName,const char * data,const size_t & totalSize)564 uint32_t ImageUtils::SaveDataToFile(const std::string& fileName, const char* data, const size_t& totalSize)
565 {
566 std::ofstream outFile(fileName, std::ofstream::out);
567 if (!outFile.is_open()) {
568 IMAGE_LOGI("ImageUtils::SaveDataToFile write error, path=%{public}s", fileName.c_str());
569 return IMAGE_RESULT_SAVE_DATA_TO_FILE_FAILED;
570 }
571 if (data == nullptr) {
572 IMAGE_LOGE("ImageUtils::SaveDataToFile data is nullptr");
573 return IMAGE_RESULT_SAVE_DATA_TO_FILE_FAILED;
574 }
575 outFile.write(data, totalSize);
576 return SUCCESS;
577 }
578
GetLocalTime()579 std::string ImageUtils::GetLocalTime()
580 {
581 // time string : "year-month-day hour_minute_second.millisecond", ':' is not supported in windows file name
582 auto now = std::chrono::system_clock::now();
583 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
584 std::time_t t = std::chrono::system_clock::to_time_t(now);
585 std::tm tm = *std::localtime(&t);
586
587 std::stringstream ss;
588 int millSecondWidth = 3;
589 ss << std::put_time(&tm, "%Y-%m-%d %H_%M_%S.") << std::setfill('0') << std::setw(millSecondWidth) << ms.count();
590 return ss.str();
591 }
592
GetPixelMapName(PixelMap * pixelMap)593 std::string ImageUtils::GetPixelMapName(PixelMap* pixelMap)
594 {
595 if (!pixelMap) {
596 IMAGE_LOGE("ImageUtils::GetPixelMapName error, pixelMap is null");
597 return "";
598 }
599 #ifdef IOS_PLATFORM
600 std::string pixelMapStr = "_pixelMap_w" + std::to_string(pixelMap->GetWidth()) +
601 "_h" + std::to_string(pixelMap->GetHeight()) +
602 "_rowStride" + std::to_string(pixelMap->GetRowStride()) +
603 "_total" + std::to_string(pixelMap->GetRowStride() * pixelMap->GetHeight()) +
604 "_pid" + std::to_string(getpid()) +
605 "_tid" + std::to_string(syscall(SYS_thread_selfid)) +
606 "_uniqueId" + std::to_string(pixelMap->GetUniqueId());
607 #else
608 std::string yuvInfoStr = "";
609 if (pixelMap->GetPixelFormat() == PixelFormat::NV12 || pixelMap->GetPixelFormat() == PixelFormat::NV21) {
610 YUVDataInfo yuvInfo;
611 pixelMap->GetImageYUVInfo(yuvInfo);
612 yuvInfoStr += "_yWidth" + std::to_string(yuvInfo.yWidth) +
613 "_yHeight" + std::to_string(yuvInfo.yHeight) +
614 "_yStride" + std::to_string(yuvInfo.yStride) +
615 "_yOffset" + std::to_string(yuvInfo.yOffset) +
616 "_uvWidth" + std::to_string(yuvInfo.uvWidth) +
617 "_uvHeight" + std::to_string(yuvInfo.uvHeight) +
618 "_uvStride" + std::to_string(yuvInfo.uvStride) +
619 "_uvOffset" + std::to_string(yuvInfo.uvOffset);
620 }
621 std::string pixelMapStr = "_pixelMap_w" + std::to_string(pixelMap->GetWidth()) +
622 "_h" + std::to_string(pixelMap->GetHeight()) +
623 "_rowStride" + std::to_string(pixelMap->GetRowStride()) +
624 "_pixelFormat" + std::to_string((int32_t)pixelMap->GetPixelFormat()) +
625 yuvInfoStr +
626 "_total" + std::to_string(pixelMap->GetRowStride() * pixelMap->GetHeight()) +
627 "_pid" + std::to_string(getpid()) +
628 "_tid" + std::to_string(gettid()) +
629 "_uniqueId" + std::to_string(pixelMap->GetUniqueId());
630 #endif
631 return pixelMapStr;
632 }
633
634 // BytesToUint16 function will modify the offset value.
BytesToUint16(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)635 uint16_t ImageUtils::BytesToUint16(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
636 {
637 uint16_t data = 0;
638 if (bytes == nullptr || offset + NUM_2 >= size) {
639 return data;
640 }
641 if (isBigEndian) {
642 data = (bytes[offset] << MOVE_BITS_8) | bytes[offset + NUM_1];
643 } else {
644 data = (bytes[offset + NUM_1] << MOVE_BITS_8) | bytes[offset];
645 }
646 offset += NUM_2;
647 return data;
648 }
649
650 // BytesToUint32 function will modify the offset value.
BytesToUint32(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)651 uint32_t ImageUtils::BytesToUint32(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
652 {
653 uint32_t data = 0;
654 if (bytes == nullptr || offset + NUM_4 >= size) {
655 return data;
656 }
657 if (isBigEndian) {
658 data = (bytes[offset] << MOVE_BITS_24) | (bytes[offset + NUM_1] << MOVE_BITS_16) |
659 (bytes[offset + NUM_2] << MOVE_BITS_8) | (bytes[offset + NUM_3]);
660 } else {
661 data = (bytes[offset + NUM_3] << MOVE_BITS_24) | (bytes[offset + NUM_2] << MOVE_BITS_16) |
662 (bytes[offset + NUM_1] << MOVE_BITS_8) | bytes[offset];
663 }
664 offset += NUM_4;
665 return data;
666 }
667
668 // BytesToInt32 function will modify the offset value.
BytesToInt32(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)669 int32_t ImageUtils::BytesToInt32(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
670 {
671 int32_t data = 0;
672 if (bytes == nullptr || offset + NUM_4 >= size) {
673 return data;
674 }
675 if (isBigEndian) {
676 data = (bytes[offset] << MOVE_BITS_24) | (bytes[offset + NUM_1] << MOVE_BITS_16) |
677 (bytes[offset + NUM_2] << MOVE_BITS_8) | (bytes[offset + NUM_3]);
678 } else {
679 data = (bytes[offset + NUM_3] << MOVE_BITS_24) | (bytes[offset + NUM_2] << MOVE_BITS_16) |
680 (bytes[offset + NUM_1] << MOVE_BITS_8) | bytes[offset];
681 }
682 offset += NUM_4;
683 return data;
684 }
685
686 // BytesToFloat function will modify the offset value.
BytesToFloat(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)687 float ImageUtils::BytesToFloat(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
688 {
689 uint32_t data = BytesToUint32(bytes, offset, size, isBigEndian);
690 union {
691 uint32_t i;
692 float f;
693 } u;
694 u.i = data;
695 return u.f;
696 }
697
Uint16ToBytes(uint16_t data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)698 void ImageUtils::Uint16ToBytes(uint16_t data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
699 {
700 uint8_t BYTE_ONE = (data >> MOVE_BITS_8) & 0xFF;
701 uint8_t BYTE_TWO = data & 0xFF;
702 if (isBigEndian) {
703 bytes[offset++] = BYTE_ONE;
704 bytes[offset++] = BYTE_TWO;
705 } else {
706 bytes[offset++] = BYTE_TWO;
707 bytes[offset++] = BYTE_ONE;
708 }
709 }
710
Uint32ToBytes(uint32_t data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)711 void ImageUtils::Uint32ToBytes(uint32_t data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
712 {
713 uint8_t BYTE_ONE = (data >> MOVE_BITS_24) & 0xFF;
714 uint8_t BYTE_TWO = (data >> MOVE_BITS_16) & 0xFF;
715 uint8_t BYTE_THREE = (data >> MOVE_BITS_8) & 0xFF;
716 uint8_t BYTE_FOUR = data & 0xFF;
717 if (isBigEndian) {
718 bytes[offset++] = BYTE_ONE;
719 bytes[offset++] = BYTE_TWO;
720 bytes[offset++] = BYTE_THREE;
721 bytes[offset++] = BYTE_FOUR;
722 } else {
723 bytes[offset++] = BYTE_FOUR;
724 bytes[offset++] = BYTE_THREE;
725 bytes[offset++] = BYTE_TWO;
726 bytes[offset++] = BYTE_ONE;
727 }
728 }
729
FloatToBytes(float data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)730 void ImageUtils::FloatToBytes(float data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
731 {
732 union {
733 uint32_t i;
734 float f;
735 } u;
736 u.f = data;
737 Uint32ToBytes(u.i, bytes, offset, isBigEndian);
738 }
739
Int32ToBytes(int32_t data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)740 void ImageUtils::Int32ToBytes(int32_t data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
741 {
742 union {
743 uint32_t uit;
744 int32_t it;
745 } u;
746 u.it = data;
747 Uint32ToBytes(u.uit, bytes, offset, isBigEndian);
748 }
749
ArrayToBytes(const uint8_t * data,uint32_t length,vector<uint8_t> & bytes,uint32_t & offset)750 void ImageUtils::ArrayToBytes(const uint8_t* data, uint32_t length, vector<uint8_t>& bytes, uint32_t& offset)
751 {
752 for (uint32_t i = 0; i < length; i++) {
753 bytes[offset++] = data[i] & 0xFF;
754 }
755 }
756
FlushSurfaceBuffer(PixelMap * pixelMap)757 void ImageUtils::FlushSurfaceBuffer(PixelMap* pixelMap)
758 {
759 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
760 if (!pixelMap || pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
761 return;
762 }
763 SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(pixelMap->GetFd());
764 if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
765 GSError err = surfaceBuffer->Map();
766 if (err != GSERROR_OK) {
767 IMAGE_LOGE("ImageUtils Map failed, GSError=%{public}d", err);
768 return;
769 }
770 err = surfaceBuffer->FlushCache();
771 if (err != GSERROR_OK) {
772 IMAGE_LOGE("ImageUtils FlushCache failed, GSError=%{public}d", err);
773 }
774 }
775 #else
776 return;
777 #endif
778 }
779
FlushContextSurfaceBuffer(ImagePlugin::DecodeContext & context)780 void ImageUtils::FlushContextSurfaceBuffer(ImagePlugin::DecodeContext& context)
781 {
782 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
783 if (context.pixelsBuffer.context == nullptr || context.allocatorType != AllocatorType::DMA_ALLOC) {
784 return;
785 }
786 SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(context.pixelsBuffer.context);
787 if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
788 GSError err = surfaceBuffer->Map();
789 if (err != GSERROR_OK) {
790 IMAGE_LOGE("ImageUtils Map failed, GSError=%{public}d", err);
791 return;
792 }
793 err = surfaceBuffer->FlushCache();
794 if (err != GSERROR_OK) {
795 IMAGE_LOGE("ImageUtils FlushCache failed, GSError=%{public}d", err);
796 }
797 }
798 #else
799 return;
800 #endif
801 }
802
InvalidateContextSurfaceBuffer(ImagePlugin::DecodeContext & context)803 void ImageUtils::InvalidateContextSurfaceBuffer(ImagePlugin::DecodeContext& context)
804 {
805 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
806 if (context.pixelsBuffer.context == nullptr || context.allocatorType != AllocatorType::DMA_ALLOC) {
807 return;
808 }
809 SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(context.pixelsBuffer.context);
810 if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
811 GSError err = surfaceBuffer->InvalidateCache();
812 if (err != GSERROR_OK) {
813 IMAGE_LOGE("ImageUtils FlushCache failed, GSError=%{public}d", err);
814 }
815 }
816 #else
817 return;
818 #endif
819 }
820
GetAstcBytesCount(const ImageInfo & imageInfo)821 size_t ImageUtils::GetAstcBytesCount(const ImageInfo& imageInfo)
822 {
823 size_t astcBytesCount = 0;
824 uint32_t blockWidth = 0;
825 uint32_t blockHeight = 0;
826
827 switch (imageInfo.pixelFormat) {
828 case PixelFormat::ASTC_4x4:
829 blockWidth = ASTC_4X4_BLOCK;
830 blockHeight = ASTC_4X4_BLOCK;
831 break;
832 case PixelFormat::ASTC_6x6:
833 blockWidth = ASTC_6X6_BLOCK;
834 blockHeight = ASTC_6X6_BLOCK;
835 break;
836 case PixelFormat::ASTC_8x8:
837 blockWidth = ASTC_8X8_BLOCK;
838 blockHeight = ASTC_8X8_BLOCK;
839 break;
840 default:
841 IMAGE_LOGE("ImageUtils GetAstcBytesCount failed, format is not supported %{public}d",
842 imageInfo.pixelFormat);
843 return 0;
844 }
845 if ((blockWidth >= ASTC_4X4_BLOCK) && (blockHeight >= ASTC_4X4_BLOCK)) {
846 astcBytesCount = ((imageInfo.size.width + blockWidth - 1) / blockWidth) *
847 ((imageInfo.size.height + blockHeight - 1) / blockHeight) * ASTC_BLOCK_SIZE + ASTC_HEADER_SIZE;
848 }
849 return astcBytesCount;
850 }
851
IsAuxiliaryPictureTypeSupported(AuxiliaryPictureType type)852 bool ImageUtils::IsAuxiliaryPictureTypeSupported(AuxiliaryPictureType type)
853 {
854 auto auxTypes = GetAllAuxiliaryPictureType();
855 return (auxTypes.find(type) != auxTypes.end());
856 }
857
IsAuxiliaryPictureEncoded(AuxiliaryPictureType type)858 bool ImageUtils::IsAuxiliaryPictureEncoded(AuxiliaryPictureType type)
859 {
860 return AuxiliaryPictureType::GAINMAP == type || AuxiliaryPictureType::UNREFOCUS_MAP == type ||
861 AuxiliaryPictureType::FRAGMENT_MAP == type;
862 }
863
IsMetadataTypeSupported(MetadataType metadataType)864 bool ImageUtils::IsMetadataTypeSupported(MetadataType metadataType)
865 {
866 if (metadataType == MetadataType::EXIF || metadataType == MetadataType::FRAGMENT) {
867 return true;
868 } else {
869 return false;
870 }
871 }
872
GetAllAuxiliaryPictureType()873 const std::set<AuxiliaryPictureType> ImageUtils::GetAllAuxiliaryPictureType()
874 {
875 static const std::set<AuxiliaryPictureType> auxTypes = {
876 AuxiliaryPictureType::GAINMAP,
877 AuxiliaryPictureType::DEPTH_MAP,
878 AuxiliaryPictureType::UNREFOCUS_MAP,
879 AuxiliaryPictureType::LINEAR_MAP,
880 AuxiliaryPictureType::FRAGMENT_MAP};
881 return auxTypes;
882 }
883
StrToUint32(const std::string & str,uint32_t & value)884 bool ImageUtils::StrToUint32(const std::string& str, uint32_t& value)
885 {
886 auto [ptr, errCode] = std::from_chars(str.data(), str.data() + str.size(), value);
887 bool ret = errCode == std::errc{} && (ptr == str.data() + str.size());
888 return ret;
889 }
890
IsInRange(uint32_t value,uint32_t minValue,uint32_t maxValue)891 bool ImageUtils::IsInRange(uint32_t value, uint32_t minValue, uint32_t maxValue)
892 {
893 return (value >= minValue) && (value <= maxValue);
894 }
895
HasOverflowed(uint32_t num1,uint32_t num2)896 bool ImageUtils::HasOverflowed(uint32_t num1, uint32_t num2)
897 {
898 return num1 > std::numeric_limits<uint32_t>::max() - num2;
899 }
900
GetEncodedHeifFormat()901 std::string ImageUtils::GetEncodedHeifFormat()
902 {
903 if (GetAPIVersion() > APIVERSION_13) {
904 return "image/heic";
905 } else {
906 return "image/heif";
907 }
908 }
909
GetAPIVersion()910 int32_t ImageUtils::GetAPIVersion()
911 {
912 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
913 uint32_t targetVersion = 0;
914 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
915 if (samgr == nullptr) {
916 IMAGE_LOGE("Get ability manager failed");
917 return FAULT_API_VERSION;
918 }
919 sptr<IRemoteObject> object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
920 if (object == nullptr) {
921 IMAGE_LOGE("Object is NULL");
922 return FAULT_API_VERSION;
923 }
924
925 sptr<OHOS::AppExecFwk::IBundleMgr> bms = iface_cast<OHOS::AppExecFwk::IBundleMgr>(object);
926 if (bms == nullptr) {
927 IMAGE_LOGE("Bundle manager service is NULL.");
928 return FAULT_API_VERSION;
929 }
930 AppExecFwk::BundleInfo bundleInfo;
931 if (bms->GetBundleInfoForSelf(0, bundleInfo) != ERR_OK) {
932 IMAGE_LOGE("Get bundle info for self failed");
933 return FAULT_API_VERSION;
934 }
935 targetVersion = bundleInfo.targetVersion;
936 int32_t apiVersionResult = static_cast<int32_t>(targetVersion % 100);
937 return apiVersionResult;
938 #else
939 return FAULT_API_VERSION;
940 #endif
941 }
942
GetReusePixelRefCount(const std::shared_ptr<PixelMap> & reusePixelmap)943 uint16_t ImageUtils::GetReusePixelRefCount(const std::shared_ptr<PixelMap> &reusePixelmap)
944 {
945 #if !defined(CROSS_PLATFORM)
946 if (reusePixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
947 return 0;
948 }
949 void* sbBuffer = reusePixelmap->GetFd();
950 if (sbBuffer != nullptr) {
951 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(sbBuffer);
952 uint16_t reusePixelRefCount = static_cast<uint16_t>(ref->GetSptrRefCount());
953 return reusePixelRefCount;
954 }
955 return 0;
956 #else
957 return 0;
958 #endif
959 }
960
CanReusePixelMap(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)961 bool ImageUtils::CanReusePixelMap(ImagePlugin::DecodeContext& context, int width,
962 int height, const std::shared_ptr<PixelMap> &reusePixelmap)
963 {
964 if (reusePixelmap == nullptr) {
965 IMAGE_LOGD("reusePixelmap is nullptr");
966 return false;
967 }
968 if (GetReusePixelRefCount(reusePixelmap) != 1) {
969 IMAGE_LOGI("reusePixelmap reference count is not equal to 1");
970 return false;
971 }
972 if ((width != reusePixelmap->GetWidth()) || (height != reusePixelmap->GetHeight())) {
973 IMAGE_LOGI("The height or width of image is not equal to reusePixelmap");
974 return false;
975 }
976 if ((reusePixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC) ||
977 (context.allocatorType != AllocatorType::DMA_ALLOC)) {
978 IMAGE_LOGI("Image allocatortype is not DMA");
979 return false;
980 }
981 return true;
982 }
983
CanReusePixelMapHdr(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)984 bool ImageUtils::CanReusePixelMapHdr(ImagePlugin::DecodeContext& context, int width,
985 int height, const std::shared_ptr<PixelMap> &reusePixelmap)
986 {
987 #if !defined(CROSS_PLATFORM)
988 if (!CanReusePixelMap(context, width, height, reusePixelmap)) {
989 return false;
990 }
991 auto hdrPixelFormat = GRAPHIC_PIXEL_FMT_RGBA_1010102;
992 SetContextHdr(context, hdrPixelFormat);
993 if ((reusePixelmap->GetPixelFormat() != PixelFormat::RGBA_1010102) ||
994 (context.info.pixelFormat != PixelFormat::RGBA_1010102)) {
995 IMAGE_LOGI("PixelFormat of Hdrimage is not equal to reusePixelmap");
996 return false;
997 }
998 return true;
999 #else
1000 return false;
1001 #endif
1002 }
1003
IsReuseYUVFormat(PixelFormat format)1004 bool IsReuseYUVFormat(PixelFormat format)
1005 {
1006 return format == PixelFormat::NV12 || format == PixelFormat::NV21;
1007 }
1008
1009 // Determine whether the reusePixelmap and decoding image are both YUV format.
IsReuseYUV(ImagePlugin::DecodeContext & context,const std::shared_ptr<PixelMap> & reusePixelmap)1010 bool ImageUtils::IsReuseYUV(ImagePlugin::DecodeContext& context, const std::shared_ptr<PixelMap> &reusePixelmap)
1011 {
1012 return IsReuseYUVFormat(reusePixelmap->GetPixelFormat()) && IsReuseYUVFormat(context.info.pixelFormat);
1013 }
1014
IsReuseRGBFormat(PixelFormat format)1015 bool IsReuseRGBFormat(PixelFormat format)
1016 {
1017 return format == PixelFormat::RGBA_8888 || format == PixelFormat::BGRA_8888;
1018 }
1019
1020 // Determine whether the reusePixelmap and decoding image are both RGB format.
IsReuseRGB(ImagePlugin::DecodeContext & context,const std::shared_ptr<PixelMap> & reusePixelmap)1021 bool ImageUtils::IsReuseRGB(ImagePlugin::DecodeContext& context, const std::shared_ptr<PixelMap> &reusePixelmap)
1022 {
1023 return IsReuseRGBFormat(reusePixelmap->GetPixelFormat()) && IsReuseRGBFormat(context.info.pixelFormat);
1024 }
1025
CanReusePixelMapSdr(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1026 bool ImageUtils::CanReusePixelMapSdr(ImagePlugin::DecodeContext& context, int width,
1027 int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1028 {
1029 if (!CanReusePixelMap(context, width, height, reusePixelmap)) {
1030 return false;
1031 }
1032 if ((reusePixelmap->GetPixelFormat() == PixelFormat::RGBA_1010102) ||
1033 (context.info.pixelFormat == PixelFormat::RGBA_1010102)) {
1034 IMAGE_LOGD("Sdr image is not RGBA 10bit");
1035 return false;
1036 }
1037 if (!IsReuseYUV(context, reusePixelmap) && !IsReuseRGB(context, reusePixelmap)) {
1038 IMAGE_LOGI("PixelFormat of Sdrimage is not equal to reusePixelmap");
1039 return false;
1040 }
1041 return true;
1042 }
1043
CanApplyMemForReusePixel(ImagePlugin::DecodeContext & context,const std::shared_ptr<PixelMap> & reusePixelmap)1044 bool CanApplyMemForReusePixel(ImagePlugin::DecodeContext& context,
1045 const std::shared_ptr<PixelMap> &reusePixelmap)
1046 {
1047 #if !defined(CROSS_PLATFORM)
1048 uint8_t *reusePixelBuffer = const_cast<uint8_t *>(reusePixelmap->GetPixels());
1049 int32_t err = ImageUtils::SurfaceBuffer_Reference(reusePixelmap->GetFd());
1050 if (err != OHOS::GSERROR_OK) {
1051 IMAGE_LOGD("reusePixelmapBuffer Reference failed");
1052 return false;
1053 }
1054 ImageUtils::SetReuseContextBuffer(context, AllocatorType::DMA_ALLOC, reusePixelBuffer,
1055 reusePixelmap->GetCapacity(), reusePixelmap->GetFd());
1056 return true;
1057 #else
1058 return false;
1059 #endif
1060 }
1061
IsSdrPixelMapReuseSuccess(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1062 bool ImageUtils::IsSdrPixelMapReuseSuccess(ImagePlugin::DecodeContext& context, int width,
1063 int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1064 {
1065 #if !defined(CROSS_PLATFORM)
1066 if (!CanReusePixelMapSdr(context, width, height, reusePixelmap)) {
1067 return false;
1068 }
1069 return CanApplyMemForReusePixel(context, reusePixelmap);
1070 #else
1071 return false;
1072 #endif
1073 }
1074
IsHdrPixelMapReuseSuccess(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1075 bool ImageUtils::IsHdrPixelMapReuseSuccess(ImagePlugin::DecodeContext& context, int width,
1076 int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1077 {
1078 #if !defined(CROSS_PLATFORM)
1079 if (!CanReusePixelMapHdr(context, width, height, reusePixelmap)) {
1080 return false;
1081 }
1082 return CanApplyMemForReusePixel(context, reusePixelmap);
1083 #else
1084 return false;
1085 #endif
1086 }
1087
SetContextHdr(ImagePlugin::DecodeContext & context,uint32_t format)1088 void ImageUtils::SetContextHdr(ImagePlugin::DecodeContext& context, uint32_t format)
1089 {
1090 #if !defined(CROSS_PLATFORM)
1091 context.info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
1092 if (format == GRAPHIC_PIXEL_FMT_RGBA_1010102) {
1093 context.pixelFormat = PixelFormat::RGBA_1010102;
1094 context.info.pixelFormat = PixelFormat::RGBA_1010102;
1095 context.grColorSpaceName = ColorManager::BT2020_HLG;
1096 } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
1097 context.pixelFormat = PixelFormat::YCBCR_P010;
1098 context.info.pixelFormat = PixelFormat::YCBCR_P010;
1099 context.grColorSpaceName = ColorManager::BT2020_HLG;
1100 }
1101 #endif
1102 }
1103
SetReuseContextBuffer(ImagePlugin::DecodeContext & context,AllocatorType type,uint8_t * ptr,uint64_t count,void * fd)1104 void ImageUtils::SetReuseContextBuffer(ImagePlugin::DecodeContext& context,
1105 AllocatorType type, uint8_t* ptr, uint64_t count, void* fd)
1106 {
1107 context.allocatorType = type;
1108 context.freeFunc = nullptr;
1109 context.pixelsBuffer.buffer = ptr;
1110 context.pixelsBuffer.bufferSize = count;
1111 context.pixelsBuffer.context = fd;
1112 }
1113 } // namespace Media
1114 } // namespace OHOS
1115