• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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