• 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 <climits>
21 #include <cmath>
22 #include <cstdint>
23 #include <cstdlib>
24 #include <string>
25 #include <fstream>
26 #include <sstream>
27 #include <chrono>
28 #include <atomic>
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 "bundle_mgr_interface.h"
51 #include "iservice_registry.h"
52 #include "ipc_skeleton.h"
53 #include "system_ability_definition.h"
54 #include "os_account_manager.h"
55 #else
56 #include "refbase.h"
57 #endif
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62 #include "libswscale/swscale.h"
63 #include "libavutil/opt.h"
64 #include "libavutil/imgutils.h"
65 #include "libavcodec/avcodec.h"
66 #ifdef __cplusplus
67 }
68 #endif
69 
70 #undef LOG_DOMAIN
71 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
72 
73 #undef LOG_TAG
74 #define LOG_TAG "imageUtils"
75 
76 namespace OHOS {
77 namespace Media {
78 using namespace std;
79 using namespace MultimediaPlugin;
80 
81 constexpr int32_t ALPHA8_BYTES = 1;
82 constexpr int32_t RGB565_BYTES = 2;
83 constexpr int32_t RGB888_BYTES = 3;
84 constexpr int32_t ARGB8888_BYTES = 4;
85 constexpr int32_t RGBA_F16_BYTES = 8;
86 constexpr int32_t NV21_BYTES = 2;  // Each pixel is sorted on 3/2 bytes.
87 constexpr uint8_t MOVE_BITS_8 = 8;
88 constexpr uint8_t MOVE_BITS_16 = 16;
89 constexpr uint8_t MOVE_BITS_24 = 24;
90 constexpr int32_t NV21P010_BYTES = 3;
91 constexpr int32_t ASTC_4X4_BYTES = 1;
92 constexpr int32_t ASTC_4X4_BLOCK = 4;
93 constexpr int32_t ASTC_6X6_BLOCK = 6;
94 constexpr int32_t ASTC_8X8_BLOCK = 8;
95 constexpr int32_t ASTC_BLOCK_SIZE = 16;
96 constexpr int32_t ASTC_HEADER_SIZE = 16;
97 constexpr uint8_t FILL_NUMBER = 3;
98 constexpr uint8_t ALIGN_NUMBER = 4;
99 constexpr int32_t DMA_SIZE = 512 * 512; // DMA minimum effective size
100 constexpr int32_t FAULT_API_VERSION = -1;
101 constexpr int32_t BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401;
102 constexpr int32_t BASE_EVEN_DIVISOR = 2;
103 constexpr float EPSILON = 1e-6;
104 constexpr int MAX_DIMENSION = INT32_MAX >> 2;
105 static bool g_pluginRegistered = false;
106 static const uint8_t NUM_0 = 0;
107 static const uint8_t NUM_1 = 1;
108 static const uint8_t NUM_2 = 2;
109 static const uint8_t NUM_3 = 3;
110 static const uint8_t NUM_4 = 4;
111 static const uint8_t NUM_5 = 5;
112 static const uint8_t NUM_6 = 6;
113 static const uint8_t NUM_7 = 7;
114 static const uint8_t INT_255 = 255;
115 static const string FILE_DIR_IN_THE_SANDBOX = "/data/storage/el2/base/files/";
116 static constexpr int32_t PLANE_Y = 0;
117 static constexpr int32_t PLANE_U = 1;
118 static constexpr int32_t PLANE_V = 2;
119 constexpr int32_t MEM_DMA = 1;
120 constexpr int32_t MEM_SHARE = 2;
121 constexpr uint32_t RGBA1010102_RGB_MASK = 0x3FF;
122 constexpr uint32_t RGBA1010102_ALPHA_MASK = 0x03;
123 
124 constexpr uint32_t RGBA1010102_R_SHIFT = 0;
125 constexpr uint32_t RGBA1010102_G_SHIFT = 10;
126 constexpr uint32_t RGBA1010102_B_SHIFT = 20;
127 constexpr uint32_t RGBA1010102_A_SHIFT = 30;
128 const std::map<PixelFormat, AVPixelFormat> FFMPEG_PIXEL_FORMAT_MAP = {
129     {PixelFormat::UNKNOWN, AV_PIX_FMT_NONE},
130     {PixelFormat::NV12, AV_PIX_FMT_NV12},
131     {PixelFormat::NV21, AV_PIX_FMT_NV21},
132     {PixelFormat::RGB_565, AV_PIX_FMT_RGB565},
133     {PixelFormat::RGBA_8888, AV_PIX_FMT_RGBA},
134     {PixelFormat::BGRA_8888, AV_PIX_FMT_BGRA},
135     {PixelFormat::ARGB_8888, AV_PIX_FMT_ARGB},
136     {PixelFormat::RGBA_F16, AV_PIX_FMT_RGBA64},
137     {PixelFormat::RGB_888, AV_PIX_FMT_RGB24},
138     {PixelFormat::YCRCB_P010, AV_PIX_FMT_P010LE},
139     {PixelFormat::YCBCR_P010, AV_PIX_FMT_P010LE},
140 };
GetFileSize(const string & pathName,size_t & size)141 bool ImageUtils::GetFileSize(const string &pathName, size_t &size)
142 {
143     if (pathName.empty()) {
144         IMAGE_LOGE("[ImageUtil]input parameter exception.");
145         return false;
146     }
147     struct stat statbuf;
148     int ret = stat(pathName.c_str(), &statbuf);
149     if (ret != 0) {
150         IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d, errno:%{public}d.", ret, errno);
151         return false;
152     }
153     size = statbuf.st_size;
154     return true;
155 }
156 
GetFileSize(const int fd,size_t & size)157 bool ImageUtils::GetFileSize(const int fd, size_t &size)
158 {
159     struct stat statbuf;
160 
161     if (fd < 0) {
162         return false;
163     }
164 
165     int ret = fstat(fd, &statbuf);
166     if (ret != 0) {
167         IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d, errno:%{public}d.", ret, errno);
168         return false;
169     }
170     size = statbuf.st_size;
171     return true;
172 }
173 
GetInputStreamSize(istream & inputStream,size_t & size)174 bool ImageUtils::GetInputStreamSize(istream &inputStream, size_t &size)
175 {
176     if (inputStream.rdbuf() == nullptr) {
177         IMAGE_LOGE("[ImageUtil]input parameter exception.");
178         return false;
179     }
180     size_t original = inputStream.tellg();
181     inputStream.seekg(0, ios_base::end);
182     size = inputStream.tellg();
183     inputStream.seekg(original);
184     return true;
185 }
186 
GetPixelBytes(const PixelFormat & pixelFormat)187 int32_t ImageUtils::GetPixelBytes(const PixelFormat &pixelFormat)
188 {
189     int pixelBytes = 0;
190     switch (pixelFormat) {
191         case PixelFormat::ARGB_8888:
192         case PixelFormat::BGRA_8888:
193         case PixelFormat::RGBA_8888:
194         case PixelFormat::RGBA_1010102:
195         case PixelFormat::CMYK:
196             pixelBytes = ARGB8888_BYTES;
197             break;
198         case PixelFormat::ALPHA_8:
199             pixelBytes = ALPHA8_BYTES;
200             break;
201         case PixelFormat::RGB_888:
202             pixelBytes = RGB888_BYTES;
203             break;
204         case PixelFormat::RGB_565:
205             pixelBytes = RGB565_BYTES;
206             break;
207         case PixelFormat::RGBA_F16:
208         case PixelFormat::RGBA_U16:
209             pixelBytes = RGBA_F16_BYTES;
210             break;
211         case PixelFormat::NV21:
212         case PixelFormat::NV12:
213             pixelBytes = NV21_BYTES;  // perl pixel 1.5 Bytes but return int so return 2
214             break;
215         case PixelFormat::ASTC_4x4:
216         case PixelFormat::ASTC_6x6:
217         case PixelFormat::ASTC_8x8:
218             pixelBytes = ASTC_4X4_BYTES;
219             break;
220         case PixelFormat::YCBCR_P010:
221         case PixelFormat::YCRCB_P010:
222             pixelBytes = NV21P010_BYTES;
223             break;
224         default:
225             IMAGE_LOGE("[ImageUtil]get pixel bytes failed, pixelFormat:%{public}d.",
226                 static_cast<int32_t>(pixelFormat));
227             break;
228     }
229     return pixelBytes;
230 }
231 
PixelFormatToAVPixelFormat(const PixelFormat & pixelFormat)232 static AVPixelFormat PixelFormatToAVPixelFormat(const PixelFormat &pixelFormat)
233 {
234     auto formatSearch = FFMPEG_PIXEL_FORMAT_MAP.find(pixelFormat);
235     return (formatSearch != FFMPEG_PIXEL_FORMAT_MAP.end()) ?
236         formatSearch->second : AVPixelFormat::AV_PIX_FMT_NONE;
237 }
238 
GetYUVByteCount(const ImageInfo & info)239 int32_t ImageUtils::GetYUVByteCount(const ImageInfo& info)
240 {
241     if (!IsYUV(info.pixelFormat)) {
242         IMAGE_LOGE("[ImageUtil]unsupported pixel format");
243         return -1;
244     }
245     if (info.size.width <= 0 || info.size.height <= 0) {
246         IMAGE_LOGE("[ImageUtil]image size error");
247         return -1;
248     }
249     AVPixelFormat avPixelFormat = PixelFormatToAVPixelFormat(info.pixelFormat);
250     if (avPixelFormat == AVPixelFormat::AV_PIX_FMT_NONE) {
251         IMAGE_LOGE("[ImageUtil]pixel format to ffmpeg pixel format failed");
252         return -1;
253     }
254     return av_image_get_buffer_size(avPixelFormat, info.size.width, info.size.height, 1);
255 }
256 
GetByteCount(ImageInfo imageInfo)257 int32_t ImageUtils::GetByteCount(ImageInfo imageInfo)
258 {
259     if (ImageUtils::IsAstc(imageInfo.pixelFormat)) {
260         return static_cast<int32_t>(ImageUtils::GetAstcBytesCount(imageInfo));
261     }
262     if (IsYUV(imageInfo.pixelFormat)) {
263         return GetYUVByteCount(imageInfo);
264     }
265     int64_t rowDataSize =
266         ImageUtils::GetRowDataSizeByPixelFormat(imageInfo.size.width, imageInfo.pixelFormat);
267     int64_t height = imageInfo.size.height;
268     int64_t byteCount = rowDataSize * height;
269     if (rowDataSize <= 0 || byteCount > INT32_MAX) {
270         IMAGE_LOGE("[PixelMap] GetByteCount failed: invalid rowDataSize or byteCount overflowed");
271         return 0;
272     }
273     return static_cast<int32_t>(byteCount);
274 }
275 
GetRowDataSizeByPixelFormat(const int32_t & width,const PixelFormat & format)276 int32_t ImageUtils::GetRowDataSizeByPixelFormat(const int32_t &width, const PixelFormat &format)
277 {
278     uint64_t uWidth = static_cast<uint64_t>(width);
279     uint64_t pixelBytes = static_cast<uint64_t>(GetPixelBytes(format));
280     uint64_t rowDataSize = 0;
281     switch (format) {
282         case PixelFormat::ALPHA_8:
283             rowDataSize = pixelBytes * ((uWidth + FILL_NUMBER) / ALIGN_NUMBER * ALIGN_NUMBER);
284             break;
285         case PixelFormat::ASTC_4x4:
286             rowDataSize = pixelBytes * (((uWidth + NUM_3) >> NUM_2) << NUM_2);
287             break;
288         case PixelFormat::ASTC_6x6:
289             rowDataSize = pixelBytes * (((uWidth + NUM_5) / NUM_6) * NUM_6);
290             break;
291         case PixelFormat::ASTC_8x8:
292             rowDataSize = pixelBytes * (((uWidth + NUM_7) >> NUM_3) << NUM_3);
293             break;
294         default:
295             rowDataSize = pixelBytes * uWidth;
296     }
297     if (rowDataSize > INT32_MAX) {
298         IMAGE_LOGE("GetRowDataSizeByPixelFormat failed: rowDataSize overflowed");
299         return -1;
300     }
301     return static_cast<int32_t>(rowDataSize);
302 }
303 
RegisterPluginServer()304 uint32_t ImageUtils::RegisterPluginServer()
305 {
306 #ifdef _WIN32
307     vector<string> pluginPaths = { "" };
308 #elif defined(_APPLE)
309     vector<string> pluginPaths = { "./" };
310 #elif defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
311     vector<string> pluginPaths = {};
312 #else
313     vector<string> pluginPaths = { "/system/etc/multimediaplugin/image" };
314 #endif
315     PluginServer &pluginServer = DelayedRefSingleton<PluginServer>::GetInstance();
316     uint32_t result = pluginServer.Register(std::move(pluginPaths));
317     if (result != SUCCESS) {
318         IMAGE_LOGE("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
319     } else {
320         g_pluginRegistered = true;
321         IMAGE_LOGD("[ImageUtil]success to register plugin server");
322     }
323     return result;
324 }
325 
GetPluginServer()326 PluginServer& ImageUtils::GetPluginServer()
327 {
328     if (!g_pluginRegistered) {
329         uint32_t result = RegisterPluginServer();
330         if (result != SUCCESS) {
331             IMAGE_LOGI("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
332         }
333     }
334     return DelayedRefSingleton<PluginServer>::GetInstance();
335 }
336 
PathToRealPath(const string & path,string & realPath)337 bool ImageUtils::PathToRealPath(const string &path, string &realPath)
338 {
339     if (path.empty()) {
340         IMAGE_LOGE("path is empty!");
341         return false;
342     }
343 
344     if ((path.length() >= PATH_MAX)) {
345         IMAGE_LOGE("path len is error, the len is: [%{public}lu]", static_cast<unsigned long>(path.length()));
346         return false;
347     }
348 
349     char tmpPath[PATH_MAX] = { 0 };
350 
351 #ifdef _WIN32
352     if (_fullpath(tmpPath, path.c_str(), path.length()) == nullptr) {
353         IMAGE_LOGW("path to _fullpath error");
354     }
355 #else
356     if (realpath(path.c_str(), tmpPath) == nullptr) {
357         IMAGE_LOGE("path to realpath is nullptr");
358         return false;
359     }
360 #endif
361 
362     realPath = tmpPath;
363     return true;
364 }
365 
FloatCompareZero(float src)366 bool ImageUtils::FloatCompareZero(float src)
367 {
368     return fabs(src - 0) < EPSILON;
369 }
370 
GetValidAlphaTypeByFormat(const AlphaType & dstType,const PixelFormat & format)371 AlphaType ImageUtils::GetValidAlphaTypeByFormat(const AlphaType &dstType, const PixelFormat &format)
372 {
373     switch (format) {
374         case PixelFormat::RGBA_8888:
375         case PixelFormat::BGRA_8888:
376         case PixelFormat::ARGB_8888:
377         case PixelFormat::RGBA_1010102:
378         case PixelFormat::RGBA_F16: {
379             break;
380         }
381         case PixelFormat::ALPHA_8: {
382             if (dstType != AlphaType::IMAGE_ALPHA_TYPE_PREMUL) {
383                 return AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
384             }
385             break;
386         }
387         case PixelFormat::RGB_888:
388         case PixelFormat::RGB_565: {
389             if (dstType != AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
390                 return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
391             }
392             break;
393         }
394         case PixelFormat::NV21:
395         case PixelFormat::NV12:
396         case PixelFormat::YCBCR_P010:
397         case PixelFormat::YCRCB_P010: {
398             if (dstType != AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
399                 return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
400             }
401             break;
402         }
403         case PixelFormat::CMYK:
404         default: {
405             IMAGE_LOGE("GetValidAlphaTypeByFormat unsupport the format(%{public}d).", format);
406             return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
407         }
408     }
409     return dstType;
410 }
411 
GetPixelMapAllocatorType(const Size & size,const PixelFormat & format,bool preferDma)412 AllocatorType ImageUtils::GetPixelMapAllocatorType(const Size &size, const PixelFormat &format, bool preferDma)
413 {
414 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
415     return IsSizeSupportDma(size) && (preferDma || (IsWidthAligned(size.width) && IsFormatSupportDma(format))) &&
416         (format == PixelFormat::RGBA_8888 || Is10Bit(format)) ?
417         AllocatorType::DMA_ALLOC : AllocatorType::SHARE_MEM_ALLOC;
418 #else
419     return AllocatorType::HEAP_ALLOC;
420 #endif
421 }
422 
IsValidImageInfo(const ImageInfo & info)423 bool ImageUtils::IsValidImageInfo(const ImageInfo &info)
424 {
425     if (info.size.width <= 0 || info.size.height <= 0 || info.size.width > MAX_DIMENSION ||
426         info.size.height > MAX_DIMENSION) {
427         IMAGE_LOGE("width(%{public}d) or height(%{public}d) is invalid.", info.size.width, info.size.height);
428         return false;
429     }
430     if (info.pixelFormat == PixelFormat::UNKNOWN || info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
431         IMAGE_LOGE("check pixelformat and alphatype is invalid.");
432         return false;
433     }
434     return true;
435 }
436 
IsValidAuxiliaryInfo(const std::shared_ptr<PixelMap> & pixelMap,const AuxiliaryPictureInfo & info)437 bool ImageUtils::IsValidAuxiliaryInfo(const std::shared_ptr<PixelMap> &pixelMap, const AuxiliaryPictureInfo &info)
438 {
439     int32_t rowSize = ImageUtils::GetRowDataSizeByPixelFormat(info.size.width, info.pixelFormat);
440     bool cond = rowSize <= 0 || info.size.height <= 0 ||
441                 rowSize > std::numeric_limits<int32_t>::max() / info.size.height;
442     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s rowSize: %{public}d, height: %{public}d may overflowed",
443                                __func__, rowSize, info.size.height);
444     uint32_t infoSize = static_cast<uint32_t>(rowSize * info.size.height);
445     uint32_t pixelsSize = pixelMap->GetCapacity();
446     cond = infoSize > pixelsSize;
447     CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s invalid infoSize: %{public}u, pixelsSize: %{public}u",
448                                __func__, infoSize, pixelsSize);
449     return true;
450 }
451 
IsAstc(PixelFormat format)452 bool ImageUtils::IsAstc(PixelFormat format)
453 {
454     return format == PixelFormat::ASTC_4x4 || format == PixelFormat::ASTC_6x6 || format == PixelFormat::ASTC_8x8;
455 }
456 
IsYUV8Bit(PixelFormat & format)457 bool IsYUV8Bit(PixelFormat &format)
458 {
459     return format == PixelFormat::NV12 || format == PixelFormat::NV21;
460 }
461 
IsYUV10Bit(PixelFormat & format)462 bool IsYUV10Bit(PixelFormat &format)
463 {
464     return format == PixelFormat::YCBCR_P010 || format == PixelFormat::YCRCB_P010;
465 }
466 
IsYUV(PixelFormat format)467 bool ImageUtils::IsYUV(PixelFormat format)
468 {
469     return IsYUV8Bit(format) || IsYUV10Bit(format);
470 }
471 
IsRGBX(PixelFormat format)472 bool ImageUtils::IsRGBX(PixelFormat format)
473 {
474     return format == PixelFormat::ARGB_8888 || format == PixelFormat::RGB_565 ||
475         format == PixelFormat::RGBA_8888 || format == PixelFormat::BGRA_8888 ||
476         format == PixelFormat::RGB_888 || format == PixelFormat::ALPHA_8 ||
477         format == PixelFormat::RGBA_F16 || format == PixelFormat::RGBA_1010102 ||
478         format == PixelFormat::RGBA_U16 || format == PixelFormat::UNKNOWN;
479 }
480 
PixelMapCreateCheckFormat(PixelFormat format)481 bool ImageUtils::PixelMapCreateCheckFormat(PixelFormat format)
482 {
483     if (IsRGBX(format)) {
484         return true;
485     }
486     if (IsYUV(format)) {
487         return true;
488     }
489     return false;
490 }
491 
CheckTlvSupportedFormat(PixelFormat format)492 bool ImageUtils::CheckTlvSupportedFormat(PixelFormat format)
493 {
494     if (format == PixelFormat::UNKNOWN || format == PixelFormat::RGBA_U16 ||
495         IsYUV8Bit(format)) {
496         return false;
497     }
498     if (IsRGBX(format)) {
499         return true;
500     }
501     if (IsYUV10Bit(format)) {
502         return true;
503     }
504     return false;
505 }
506 
IsWidthAligned(const int32_t & width)507 bool ImageUtils::IsWidthAligned(const int32_t &width)
508 {
509     return ((static_cast<uint32_t>(width) * NUM_4) & INT_255) == 0;
510 }
511 
IsSizeSupportDma(const Size & size)512 bool ImageUtils::IsSizeSupportDma(const Size &size)
513 {
514     // Check for overflow risk
515     if (size.width > 0 && size.height > INT_MAX / size.width) {
516         return false;
517     }
518     return size.width * size.height >= DMA_SIZE;
519 }
520 
IsFormatSupportDma(const PixelFormat & format)521 bool ImageUtils::IsFormatSupportDma(const PixelFormat &format)
522 {
523     return format == PixelFormat::UNKNOWN || format == PixelFormat::RGBA_8888;
524 }
525 
Is10Bit(const PixelFormat & format)526 bool ImageUtils::Is10Bit(const PixelFormat &format)
527 {
528     return format == PixelFormat::RGBA_1010102 ||
529         format == PixelFormat::YCRCB_P010 || format == PixelFormat::YCBCR_P010;
530 }
531 
CheckMulOverflow(int32_t width,int32_t bytesPerPixel)532 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t bytesPerPixel)
533 {
534     if (width == 0 || bytesPerPixel == 0) {
535         IMAGE_LOGE("param is 0");
536         return true;
537     }
538     int32_t rowSize = width * bytesPerPixel;
539     if ((rowSize / width) != bytesPerPixel) {
540         IMAGE_LOGE("width * bytesPerPixel overflow!");
541         return true;
542     }
543     return false;
544 }
545 
CheckMulOverflow(int32_t width,int32_t height,int32_t bytesPerPixel)546 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t height, int32_t bytesPerPixel)
547 {
548     if (width == 0 || height == 0 || bytesPerPixel == 0) {
549         IMAGE_LOGE("param is 0");
550         return true;
551     }
552     int32_t rectSize = width * height;
553     if ((rectSize / width) != height) {
554         IMAGE_LOGE("width * height overflow!");
555         return true;
556     }
557     int32_t bufferSize = rectSize * bytesPerPixel;
558     if ((bufferSize / bytesPerPixel) != rectSize) {
559         IMAGE_LOGE("bytesPerPixel overflow!");
560         return true;
561     }
562     return false;
563 }
564 
ReversePixels(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)565 static void ReversePixels(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
566 {
567     if (byteCount % NUM_4 != NUM_0) {
568         IMAGE_LOGE("Pixel count must multiple of 4.");
569         return;
570     }
571     uint8_t *src = srcPixels;
572     uint8_t *dst = dstPixels;
573     for (uint32_t i = NUM_0 ; i < byteCount; i += NUM_4) {
574         // 0-B 1-G 2-R 3-A
575         dst[NUM_0] = src[NUM_3];
576         dst[NUM_1] = src[NUM_2];
577         dst[NUM_2] = src[NUM_1];
578         dst[NUM_3] = src[NUM_0];
579         src += NUM_4;
580         dst += NUM_4;
581     }
582 }
583 
BGRAToARGB(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)584 void ImageUtils::BGRAToARGB(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
585 {
586     ImageTrace imageTrace("BGRAToARGB");
587     ReversePixels(srcPixels, dstPixels, byteCount);
588 }
589 
ARGBToBGRA(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)590 void ImageUtils::ARGBToBGRA(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
591 {
592     ReversePixels(srcPixels, dstPixels, byteCount);
593 }
594 
SurfaceBuffer_Reference(void * buffer)595 int32_t ImageUtils::SurfaceBuffer_Reference(void* buffer)
596 {
597     if (buffer == nullptr) {
598         IMAGE_LOGE("parameter error, please check input parameter");
599         return ERR_SURFACEBUFFER_REFERENCE_FAILED;
600     }
601     OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
602     ref->IncStrongRef(ref);
603     return SUCCESS;
604 }
605 
SurfaceBuffer_Unreference(void * buffer)606 int32_t ImageUtils::SurfaceBuffer_Unreference(void* buffer)
607 {
608     if (buffer == nullptr) {
609         IMAGE_LOGE("parameter error, please check input parameter");
610         return ERR_SURFACEBUFFER_UNREFERENCE_FAILED;
611     }
612     OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
613     ref->DecStrongRef(ref);
614     return SUCCESS;
615 }
616 
DumpPixelMap(PixelMap * pixelMap,std::string customFileName,uint64_t imageId)617 void ImageUtils::DumpPixelMap(PixelMap* pixelMap, std::string customFileName, uint64_t imageId)
618 {
619     IMAGE_LOGI("ImageUtils::DumpPixelMap start");
620     std::string fileName = FILE_DIR_IN_THE_SANDBOX + GetLocalTime() + customFileName + std::to_string(imageId) +
621         GetPixelMapName(pixelMap) + ".dat";
622     int32_t totalSize = pixelMap->GetRowStride() * pixelMap->GetHeight();
623     PixelFormat pixelFormat = pixelMap->GetPixelFormat();
624     if (pixelFormat == PixelFormat::NV12 || pixelFormat == PixelFormat::NV21 ||
625         pixelFormat == PixelFormat::YCBCR_P010 || pixelFormat == PixelFormat::YCRCB_P010) {
626 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
627         if (pixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
628             auto sbBuffer = reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
629             if (!sbBuffer) {
630                 return;
631             }
632             totalSize = static_cast<int32_t>(sbBuffer->GetSize());
633         } else {
634             totalSize = static_cast<int32_t>(pixelMap->GetCapacity());
635         }
636 #else
637         totalSize = static_cast<int32_t>(pixelMap->GetCapacity());
638 #endif
639         IMAGE_LOGI("ImageUtils::DumpPixelMapIfDumpEnabled YUV420 totalSize is %{public}d", totalSize);
640     }
641     if (SUCCESS != SaveDataToFile(fileName, reinterpret_cast<const char*>(pixelMap->GetPixels()), totalSize)) {
642         IMAGE_LOGI("ImageUtils::DumpPixelMap failed");
643         return;
644     }
645     IMAGE_LOGI("ImageUtils::DumpPixelMap success, path = %{public}s", fileName.c_str());
646 }
647 
DumpPixelMapIfDumpEnabled(std::unique_ptr<PixelMap> & pixelMap,uint64_t imageId)648 void ImageUtils::DumpPixelMapIfDumpEnabled(std::unique_ptr<PixelMap>& pixelMap, uint64_t imageId)
649 {
650     if (!ImageSystemProperties::GetDumpImageEnabled()) {
651         return;
652     }
653     if (pixelMap == nullptr) {
654         IMAGE_LOGI("ImageUtils::DumpPixelMapIfDumpEnabled pixelMap is null");
655         return;
656     }
657     DumpPixelMap(pixelMap.get(), "_imageId", imageId);
658 }
659 
DumpPixelMapIfDumpEnabled(PixelMap & pixelMap,std::string func)660 void ImageUtils::DumpPixelMapIfDumpEnabled(PixelMap& pixelMap, std::string func)
661 {
662     if (!ImageSystemProperties::GetDumpImageEnabled()) {
663         return;
664     }
665     DumpPixelMap(&pixelMap, "_imageId_" + func + "_");
666 }
667 
DumpPixelMapBeforeEncode(PixelMap & pixelMap)668 void ImageUtils::DumpPixelMapBeforeEncode(PixelMap& pixelMap)
669 {
670     if (!ImageSystemProperties::GetDumpImageEnabled()) {
671         return;
672     }
673     DumpPixelMap(&pixelMap, "_beforeEncode");
674 }
675 
DumpDataIfDumpEnabled(const char * data,const size_t & totalSize,const std::string & fileSuffix,uint64_t imageId)676 void ImageUtils::DumpDataIfDumpEnabled(const char* data, const size_t& totalSize,
677     const std::string& fileSuffix, uint64_t imageId)
678 {
679     if (!ImageSystemProperties::GetDumpImageEnabled()) {
680         return;
681     }
682     std::string fileName = FILE_DIR_IN_THE_SANDBOX + GetLocalTime() + "_imageId" + std::to_string(imageId) +
683         "_data_total" + std::to_string(totalSize) + "." + fileSuffix;
684     if (SUCCESS != SaveDataToFile(fileName, data, totalSize)) {
685         IMAGE_LOGI("ImageUtils::DumpDataIfDumpEnabled failed");
686         return;
687     }
688     IMAGE_LOGI("ImageUtils::DumpDataIfDumpEnabled success, path = %{public}s", fileName.c_str());
689 }
690 
GetNowTimeMilliSeconds()691 uint64_t ImageUtils::GetNowTimeMilliSeconds()
692 {
693     auto now = std::chrono::system_clock::now();
694     return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
695 }
696 
GetNowTimeMicroSeconds()697 uint64_t ImageUtils::GetNowTimeMicroSeconds()
698 {
699     auto now = std::chrono::system_clock::now();
700     return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
701 }
702 
GetCurrentProcessName()703 std::string ImageUtils::GetCurrentProcessName()
704 {
705     std::string processName;
706     std::ifstream cmdlineFile("/proc/self/cmdline");
707     if (cmdlineFile.is_open()) {
708         std::ostringstream oss;
709         oss << cmdlineFile.rdbuf();
710         cmdlineFile.close();
711 
712         //Extrace process name from the command line
713         std::string cmdline = oss.str();
714         size_t pos = cmdline.find_first_of('\0');
715         if (pos != std::string::npos) {
716             processName = cmdline.substr(0, pos);
717         }
718     }
719     return processName;
720 }
721 
SetInitializationOptionAutoMem(InitializationOptions & option)722 bool ImageUtils::SetInitializationOptionAutoMem(InitializationOptions &option)
723 {
724     if (option.pixelFormat == PixelFormat::RGBA_1010102||
725         option.pixelFormat == PixelFormat::YCBCR_P010||
726         option.pixelFormat == PixelFormat::YCRCB_P010) {
727         option.allocatorType = AllocatorType::DMA_ALLOC;
728         option.useDMA = true;
729         return true;
730     }
731     if (option.size.width * option.size.height >= DMA_SIZE) {
732         if (SetInitializationOptionDmaMem(option)) {
733             return true;
734         }
735     }
736     option.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
737     option.useDMA = false;
738     return true;
739 }
740 
SetInitializationOptionDmaMem(InitializationOptions & option)741 bool ImageUtils::SetInitializationOptionDmaMem(InitializationOptions &option)
742 {
743     switch (option.pixelFormat) {
744         case PixelFormat::RGB_565:
745         case PixelFormat::RGBA_8888:
746         case PixelFormat::BGRA_8888:
747         case PixelFormat::RGBA_F16:
748         case PixelFormat::RGBA_1010102:
749         case PixelFormat::YCBCR_P010:
750         case PixelFormat::YCRCB_P010:
751             option.allocatorType = AllocatorType::DMA_ALLOC;
752             option.useDMA = true;
753             return true;
754         default:
755             IMAGE_LOGE("pixelformat:%{public}d is not surport DMA.", option.pixelFormat);
756             return false;
757     }
758     return false;
759 }
760 
SetInitializationOptionAllocatorType(InitializationOptions & option,int32_t allocatorType)761 bool ImageUtils::SetInitializationOptionAllocatorType(InitializationOptions &option, int32_t allocatorType)
762 {
763     if (allocatorType > NUM_2 || allocatorType < 0) {
764         IMAGE_LOGE("allocatorType is invalided.");
765         return false;
766     }
767     switch (allocatorType) {
768         case MEM_DMA:
769             return SetInitializationOptionDmaMem(option);
770         case MEM_SHARE:
771             if (option.pixelFormat == PixelFormat::RGBA_1010102 ||
772                 option.pixelFormat == PixelFormat::YCBCR_P010 ||
773                 option.pixelFormat == PixelFormat::YCRCB_P010) {
774                 IMAGE_LOGE("pixelFormat is unsupport:%{public}d.", option.pixelFormat);
775                 return false;
776             }
777             option.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
778             option.useDMA = false;
779             return true;
780         default:
781             return SetInitializationOptionAutoMem(option);
782     }
783     return true;
784 }
785 
SaveDataToFile(const std::string & fileName,const char * data,const size_t & totalSize)786 uint32_t ImageUtils::SaveDataToFile(const std::string& fileName, const char* data, const size_t& totalSize)
787 {
788     std::ofstream outFile(fileName, std::ofstream::out);
789     if (!outFile.is_open()) {
790         IMAGE_LOGI("ImageUtils::SaveDataToFile write error, path=%{public}s", fileName.c_str());
791         return IMAGE_RESULT_SAVE_DATA_TO_FILE_FAILED;
792     }
793     if (data == nullptr) {
794         IMAGE_LOGE("ImageUtils::SaveDataToFile data is nullptr");
795         return IMAGE_RESULT_SAVE_DATA_TO_FILE_FAILED;
796     }
797     outFile.write(data, totalSize);
798     return SUCCESS;
799 }
800 
GetLocalTime()801 std::string ImageUtils::GetLocalTime()
802 {
803     // time string : "year-month-day hour_minute_second.millisecond", ':' is not supported in windows file name
804     auto now = std::chrono::system_clock::now();
805     auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
806     std::time_t t = std::chrono::system_clock::to_time_t(now);
807     std::tm* tm = std::localtime(&t);
808     if (tm == nullptr) {
809         IMAGE_LOGE("ImageUtils::GetLocalTime error, returned nullptr");
810         return "";
811     }
812 
813     std::stringstream ss;
814     int millSecondWidth = 3;
815     ss << std::put_time(tm, "%Y-%m-%d %H_%M_%S.") << std::setfill('0') << std::setw(millSecondWidth) << ms.count();
816     return ss.str();
817 }
818 
GetPixelMapName(PixelMap * pixelMap)819 std::string ImageUtils::GetPixelMapName(PixelMap* pixelMap)
820 {
821     if (!pixelMap) {
822         IMAGE_LOGE("ImageUtils::GetPixelMapName error, pixelMap is null");
823         return "";
824     }
825 #ifdef IOS_PLATFORM
826     std::string pixelMapStr = "_pixelMap_w" + std::to_string(pixelMap->GetWidth()) +
827         "_h" + std::to_string(pixelMap->GetHeight()) +
828         "_rowStride" + std::to_string(pixelMap->GetRowStride()) +
829         "_pixelFormat" + std::to_string((int32_t)pixelMap->GetPixelFormat()) +
830         "_total" + std::to_string(pixelMap->GetRowStride() * pixelMap->GetHeight()) +
831         "_pid" + std::to_string(getpid()) +
832         "_tid" + std::to_string(syscall(SYS_thread_selfid)) +
833         "_uniqueId" + std::to_string(pixelMap->GetUniqueId());
834 #else
835     std::string yuvInfoStr = "";
836     if (pixelMap->GetPixelFormat() == PixelFormat::NV12 || pixelMap->GetPixelFormat() == PixelFormat::NV21) {
837         YUVDataInfo yuvInfo;
838         pixelMap->GetImageYUVInfo(yuvInfo);
839         yuvInfoStr += "_yWidth" + std::to_string(yuvInfo.yWidth) +
840             "_yHeight" + std::to_string(yuvInfo.yHeight) +
841             "_yStride" + std::to_string(yuvInfo.yStride) +
842             "_yOffset" + std::to_string(yuvInfo.yOffset) +
843             "_uvWidth" + std::to_string(yuvInfo.uvWidth) +
844             "_uvHeight" + std::to_string(yuvInfo.uvHeight) +
845             "_uvStride" + std::to_string(yuvInfo.uvStride) +
846             "_uvOffset" + std::to_string(yuvInfo.uvOffset);
847     }
848     std::string pixelMapStr = "_pixelMap_w" + std::to_string(pixelMap->GetWidth()) +
849         "_h" + std::to_string(pixelMap->GetHeight()) +
850         "_rowStride" + std::to_string(pixelMap->GetRowStride()) +
851         "_pixelFormat" + std::to_string((int32_t)pixelMap->GetPixelFormat()) +
852         "_total" + std::to_string(pixelMap->GetRowStride() * pixelMap->GetHeight()) +
853         "_pid" + std::to_string(getpid()) +
854         "_tid" + std::to_string(gettid()) +
855         "_uniqueId" + std::to_string(pixelMap->GetUniqueId());
856 #endif
857     return pixelMapStr;
858 }
859 
860  // BytesToUint16 function will modify the offset value.
BytesToUint16(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)861 uint16_t ImageUtils::BytesToUint16(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
862 {
863     uint16_t data = 0;
864     if (bytes == nullptr || offset + NUM_2 > size) {
865         return data;
866     }
867     if (isBigEndian) {
868         data = (bytes[offset] << MOVE_BITS_8) | bytes[offset + NUM_1];
869     } else {
870         data = (bytes[offset + NUM_1] << MOVE_BITS_8) | bytes[offset];
871     }
872     offset += NUM_2;
873     return data;
874 }
875 
876 // BytesToUint32 function will modify the offset value.
BytesToUint32(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)877 uint32_t ImageUtils::BytesToUint32(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
878 {
879     uint32_t data = 0;
880     if (bytes == nullptr || offset + NUM_4 > size) {
881         return data;
882     }
883     if (isBigEndian) {
884         data = (bytes[offset] << MOVE_BITS_24) | (bytes[offset + NUM_1] << MOVE_BITS_16) |
885                 (bytes[offset + NUM_2] << MOVE_BITS_8) | (bytes[offset + NUM_3]);
886     } else {
887         data = (bytes[offset + NUM_3] << MOVE_BITS_24) | (bytes[offset + NUM_2] << MOVE_BITS_16) |
888                 (bytes[offset + NUM_1] << MOVE_BITS_8) | bytes[offset];
889     }
890     offset += NUM_4;
891     return data;
892 }
893 
894 // BytesToInt32 function will modify the offset value.
BytesToInt32(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)895 int32_t ImageUtils::BytesToInt32(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
896 {
897     int32_t data = 0;
898     if (bytes == nullptr || offset + NUM_4 > size) {
899         return data;
900     }
901     if (isBigEndian) {
902         data = (bytes[offset] << MOVE_BITS_24) | (bytes[offset + NUM_1] << MOVE_BITS_16) |
903                 (bytes[offset + NUM_2] << MOVE_BITS_8) | (bytes[offset + NUM_3]);
904     } else {
905         data = (bytes[offset + NUM_3] << MOVE_BITS_24) | (bytes[offset + NUM_2] << MOVE_BITS_16) |
906                 (bytes[offset + NUM_1] << MOVE_BITS_8) | bytes[offset];
907     }
908     offset += NUM_4;
909     return data;
910 }
911 
912 // BytesToFloat function will modify the offset value.
BytesToFloat(uint8_t * bytes,uint32_t & offset,uint32_t size,bool isBigEndian)913 float ImageUtils::BytesToFloat(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian)
914 {
915     uint32_t data = BytesToUint32(bytes, offset, size, isBigEndian);
916     union {
917         uint32_t i;
918         float f;
919     } u;
920     u.i = data;
921     return u.f;
922 }
923 
Uint16ToBytes(uint16_t data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)924 void ImageUtils::Uint16ToBytes(uint16_t data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
925 {
926     uint8_t BYTE_ONE = (data >> MOVE_BITS_8) & 0xFF;
927     uint8_t BYTE_TWO = data & 0xFF;
928     if (isBigEndian) {
929         bytes[offset++] = BYTE_ONE;
930         bytes[offset++] = BYTE_TWO;
931     } else {
932         bytes[offset++] = BYTE_TWO;
933         bytes[offset++] = BYTE_ONE;
934     }
935 }
936 
Uint32ToBytes(uint32_t data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)937 void ImageUtils::Uint32ToBytes(uint32_t data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
938 {
939     uint8_t BYTE_ONE = (data >> MOVE_BITS_24) & 0xFF;
940     uint8_t BYTE_TWO = (data >> MOVE_BITS_16) & 0xFF;
941     uint8_t BYTE_THREE = (data >> MOVE_BITS_8) & 0xFF;
942     uint8_t BYTE_FOUR = data & 0xFF;
943     if (isBigEndian) {
944         bytes[offset++] = BYTE_ONE;
945         bytes[offset++] = BYTE_TWO;
946         bytes[offset++] = BYTE_THREE;
947         bytes[offset++] = BYTE_FOUR;
948     } else {
949         bytes[offset++] = BYTE_FOUR;
950         bytes[offset++] = BYTE_THREE;
951         bytes[offset++] = BYTE_TWO;
952         bytes[offset++] = BYTE_ONE;
953     }
954 }
955 
FloatToBytes(float data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)956 void ImageUtils::FloatToBytes(float data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
957 {
958     union {
959         uint32_t i;
960         float f;
961     } u;
962     u.f = data;
963     Uint32ToBytes(u.i, bytes, offset, isBigEndian);
964 }
965 
Int32ToBytes(int32_t data,vector<uint8_t> & bytes,uint32_t & offset,bool isBigEndian)966 void ImageUtils::Int32ToBytes(int32_t data, vector<uint8_t>& bytes, uint32_t& offset, bool isBigEndian)
967 {
968     union {
969         uint32_t uit;
970         int32_t it;
971     } u;
972     u.it = data;
973     Uint32ToBytes(u.uit, bytes, offset, isBigEndian);
974 }
975 
ArrayToBytes(const uint8_t * data,uint32_t length,vector<uint8_t> & bytes,uint32_t & offset)976 void ImageUtils::ArrayToBytes(const uint8_t* data, uint32_t length, vector<uint8_t>& bytes, uint32_t& offset)
977 {
978     for (uint32_t i = 0; i < length; i++) {
979         bytes[offset++] = data[i] & 0xFF;
980     }
981 }
982 
983 #if !defined(CROSS_PLATFORM)
FlushSurfaceBuffer(sptr<SurfaceBuffer> & surfaceBuffer)984 void ImageUtils::FlushSurfaceBuffer(sptr<SurfaceBuffer>& surfaceBuffer)
985 {
986     if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
987         GSError err = surfaceBuffer->FlushCache();
988         bool cond = err != GSERROR_OK;
989         CHECK_ERROR_PRINT_LOG(cond, "ImageUtils FlushCache failed, GSError=%{public}d", err);
990     }
991 }
992 #endif
993 
FlushSurfaceBuffer(PixelMap * pixelMap)994 void ImageUtils::FlushSurfaceBuffer(PixelMap* pixelMap)
995 {
996 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
997     if (!pixelMap || pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
998         return;
999     }
1000     SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(pixelMap->GetFd());
1001     if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
1002         GSError err = surfaceBuffer->Map();
1003         if (err != GSERROR_OK) {
1004             IMAGE_LOGE("ImageUtils Map failed, GSError=%{public}d", err);
1005             return;
1006         }
1007         err = surfaceBuffer->FlushCache();
1008         if (err != GSERROR_OK) {
1009             IMAGE_LOGE("ImageUtils FlushCache failed, GSError=%{public}d", err);
1010         }
1011     }
1012 #else
1013     return;
1014 #endif
1015 }
1016 
FlushContextSurfaceBuffer(ImagePlugin::DecodeContext & context)1017 void ImageUtils::FlushContextSurfaceBuffer(ImagePlugin::DecodeContext& context)
1018 {
1019 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1020     if (context.pixelsBuffer.context == nullptr || context.allocatorType != AllocatorType::DMA_ALLOC) {
1021         return;
1022     }
1023     SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(context.pixelsBuffer.context);
1024     if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
1025         GSError err = surfaceBuffer->Map();
1026         if (err != GSERROR_OK) {
1027             IMAGE_LOGE("ImageUtils Map failed, GSError=%{public}d", err);
1028             return;
1029         }
1030         err = surfaceBuffer->FlushCache();
1031         if (err != GSERROR_OK) {
1032             IMAGE_LOGE("ImageUtils FlushCache failed, GSError=%{public}d", err);
1033         }
1034     }
1035 #else
1036     return;
1037 #endif
1038 }
1039 
InvalidateContextSurfaceBuffer(ImagePlugin::DecodeContext & context)1040 void ImageUtils::InvalidateContextSurfaceBuffer(ImagePlugin::DecodeContext& context)
1041 {
1042 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1043     bool cond = context.pixelsBuffer.context == nullptr || context.allocatorType != AllocatorType::DMA_ALLOC;
1044     CHECK_ERROR_RETURN(cond);
1045     SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(context.pixelsBuffer.context);
1046     if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
1047         GSError err = surfaceBuffer->InvalidateCache();
1048         cond = err != GSERROR_OK;
1049         CHECK_ERROR_PRINT_LOG(cond, "ImageUtils FlushCache failed, GSError=%{public}d", err);
1050     }
1051 #else
1052     return;
1053 #endif
1054 }
1055 
IsAuxiliaryPictureTypeSupported(AuxiliaryPictureType type)1056 bool ImageUtils::IsAuxiliaryPictureTypeSupported(AuxiliaryPictureType type)
1057 {
1058     auto auxTypes = GetAllAuxiliaryPictureType();
1059     return (auxTypes.find(type) != auxTypes.end());
1060 }
1061 
IsAuxiliaryPictureEncoded(AuxiliaryPictureType type)1062 bool ImageUtils::IsAuxiliaryPictureEncoded(AuxiliaryPictureType type)
1063 {
1064     return AuxiliaryPictureType::GAINMAP == type || AuxiliaryPictureType::UNREFOCUS_MAP == type ||
1065         AuxiliaryPictureType::FRAGMENT_MAP == type;
1066 }
1067 
IsMetadataTypeSupported(MetadataType metadataType)1068 bool ImageUtils::IsMetadataTypeSupported(MetadataType metadataType)
1069 {
1070     if (metadataType == MetadataType::EXIF || metadataType == MetadataType::FRAGMENT) {
1071         return true;
1072     } else {
1073         return false;
1074     }
1075 }
1076 
GetAllAuxiliaryPictureType()1077 const std::set<AuxiliaryPictureType> ImageUtils::GetAllAuxiliaryPictureType()
1078 {
1079     static const std::set<AuxiliaryPictureType> auxTypes = {
1080         AuxiliaryPictureType::GAINMAP,
1081         AuxiliaryPictureType::DEPTH_MAP,
1082         AuxiliaryPictureType::UNREFOCUS_MAP,
1083         AuxiliaryPictureType::LINEAR_MAP,
1084         AuxiliaryPictureType::FRAGMENT_MAP};
1085     return auxTypes;
1086 }
1087 
GetAstcBytesCount(const ImageInfo & imageInfo)1088 size_t ImageUtils::GetAstcBytesCount(const ImageInfo& imageInfo)
1089 {
1090     size_t astcBytesCount = 0;
1091     uint32_t blockWidth = 0;
1092     uint32_t blockHeight = 0;
1093 
1094     switch (imageInfo.pixelFormat) {
1095         case PixelFormat::ASTC_4x4:
1096             blockWidth = ASTC_4X4_BLOCK;
1097             blockHeight = ASTC_4X4_BLOCK;
1098             break;
1099         case PixelFormat::ASTC_6x6:
1100             blockWidth = ASTC_6X6_BLOCK;
1101             blockHeight = ASTC_6X6_BLOCK;
1102             break;
1103         case PixelFormat::ASTC_8x8:
1104             blockWidth = ASTC_8X8_BLOCK;
1105             blockHeight = ASTC_8X8_BLOCK;
1106             break;
1107         default:
1108             IMAGE_LOGE("ImageUtils GetAstcBytesCount failed, format is not supported %{public}d",
1109                 imageInfo.pixelFormat);
1110             return 0;
1111     }
1112     if ((blockWidth >= ASTC_4X4_BLOCK) && (blockHeight >= ASTC_4X4_BLOCK)) {
1113         astcBytesCount = ((imageInfo.size.width + blockWidth - 1) / blockWidth) *
1114             ((imageInfo.size.height + blockHeight - 1) / blockHeight) * ASTC_BLOCK_SIZE + ASTC_HEADER_SIZE;
1115     }
1116     return astcBytesCount;
1117 }
1118 
StrToUint32(const std::string & str,uint32_t & value)1119 bool ImageUtils::StrToUint32(const std::string& str, uint32_t& value)
1120 {
1121     if (str.empty() || !isdigit(str.front())) {
1122         return false;
1123     }
1124 
1125     char* end = nullptr;
1126     errno = 0;
1127     auto addr = str.c_str();
1128     auto result = strtoul(addr, &end, 10); /* 10 means decimal */
1129     if ((end == addr) || (end[0] != '\0') || (errno == ERANGE) ||
1130         (result > UINT32_MAX)) {
1131         return false;
1132     }
1133     value = static_cast<uint32_t>(result);
1134     return true;
1135 }
1136 
IsInRange(uint32_t value,uint32_t minValue,uint32_t maxValue)1137 bool ImageUtils::IsInRange(uint32_t value, uint32_t minValue, uint32_t maxValue)
1138 {
1139     return (value >= minValue) && (value <= maxValue);
1140 }
1141 
IsInRange(int32_t value,int32_t minValue,int32_t maxValue)1142 bool ImageUtils::IsInRange(int32_t value, int32_t minValue, int32_t maxValue)
1143 {
1144     return (value >= minValue) && (value <= maxValue);
1145 }
1146 
IsEven(int32_t value)1147 bool ImageUtils::IsEven(int32_t value)
1148 {
1149     return value % BASE_EVEN_DIVISOR == 0;
1150 }
1151 
HasOverflowed(uint32_t num1,uint32_t num2)1152 bool ImageUtils::HasOverflowed(uint32_t num1, uint32_t num2)
1153 {
1154     return num1 > std::numeric_limits<uint32_t>::max() - num2;
1155 }
1156 
GetEncodedHeifFormat()1157 std::string ImageUtils::GetEncodedHeifFormat()
1158 {
1159     if (GetAPIVersion() > APIVERSION_13) {
1160         return "image/heic";
1161     } else {
1162         return "image/heif";
1163     }
1164 }
1165 
GetAPIVersion()1166 int32_t ImageUtils::GetAPIVersion()
1167 {
1168 #if !defined(CROSS_PLATFORM)
1169     static std::atomic<int32_t> apiVersion = GetAPIVersionInner();
1170     if (apiVersion.load() <= 0) {
1171         apiVersion.store(GetAPIVersionInner());
1172     }
1173     return apiVersion.load();
1174 #else
1175     return FAULT_API_VERSION;
1176 #endif
1177 }
1178 
GetAPIVersionInner()1179 int32_t ImageUtils::GetAPIVersionInner()
1180 {
1181 #if !defined(CROSS_PLATFORM)
1182     uint32_t targetVersion = 0;
1183     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1184     if (samgr == nullptr) {
1185         IMAGE_LOGE("Get ability manager failed");
1186         return FAULT_API_VERSION;
1187     }
1188     sptr<IRemoteObject> object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
1189     if (object == nullptr) {
1190         IMAGE_LOGE("Object is NULL");
1191         return FAULT_API_VERSION;
1192     }
1193 
1194     sptr<OHOS::AppExecFwk::IBundleMgr> bms = iface_cast<OHOS::AppExecFwk::IBundleMgr>(object);
1195     if (bms == nullptr) {
1196         IMAGE_LOGE("Bundle manager service is NULL.");
1197         return FAULT_API_VERSION;
1198     }
1199     AppExecFwk::BundleInfo bundleInfo;
1200     if (bms->GetBundleInfoForSelf(0, bundleInfo) != ERR_OK) {
1201         IMAGE_LOGD("Get bundle info for self failed");
1202         return FAULT_API_VERSION;
1203     }
1204     targetVersion = bundleInfo.targetVersion;
1205     int32_t apiVersionResult = static_cast<int32_t>(targetVersion % 100);
1206     return apiVersionResult;
1207 #else
1208     return FAULT_API_VERSION;
1209 #endif
1210 }
1211 
1212 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
GetYUVStrideInfo(int32_t pixelFmt,OH_NativeBuffer_Planes * planes,YUVStrideInfo & dstStrides)1213 static void GetYUVStrideInfo(int32_t pixelFmt, OH_NativeBuffer_Planes *planes, YUVStrideInfo &dstStrides)
1214 {
1215     if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
1216         auto yStride = planes->planes[PLANE_Y].columnStride;
1217         auto uvStride = planes->planes[PLANE_U].columnStride;
1218         auto yOffset = planes->planes[PLANE_Y].offset;
1219         auto uvOffset = planes->planes[PLANE_U].offset;
1220         dstStrides = {yStride, uvStride, yOffset, uvOffset};
1221     } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
1222         auto yStride = planes->planes[PLANE_Y].columnStride;
1223         auto uvStride = planes->planes[PLANE_V].columnStride;
1224         auto yOffset = planes->planes[PLANE_Y].offset;
1225         auto uvOffset = planes->planes[PLANE_V].offset;
1226         dstStrides = {yStride, uvStride, yOffset, uvOffset};
1227     } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
1228         auto yStride = planes->planes[PLANE_Y].columnStride / 2;
1229         auto uvStride = planes->planes[PLANE_U].columnStride / 2;
1230         auto yOffset = planes->planes[PLANE_Y].offset / 2;
1231         auto uvOffset = planes->planes[PLANE_U].offset / 2;
1232         dstStrides = {yStride, uvStride, yOffset, uvOffset};
1233     } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
1234         auto yStride = planes->planes[PLANE_Y].columnStride / 2;
1235         auto uvStride = planes->planes[PLANE_V].columnStride / 2;
1236         auto yOffset = planes->planes[PLANE_Y].offset / 2;
1237         auto uvOffset = planes->planes[PLANE_V].offset / 2;
1238         dstStrides = {yStride, uvStride, yOffset, uvOffset};
1239     }
1240 }
1241 #endif
1242 
UpdateSdrYuvStrides(const ImageInfo & imageInfo,YUVStrideInfo & dstStrides,void * context,AllocatorType dstType)1243 void ImageUtils::UpdateSdrYuvStrides(const ImageInfo &imageInfo, YUVStrideInfo &dstStrides,
1244     void *context, AllocatorType dstType)
1245 {
1246     int32_t dstWidth = imageInfo.size.width;
1247     int32_t dstHeight = imageInfo.size.height;
1248     int32_t dstYStride = dstWidth;
1249     int32_t dstUvStride = (dstWidth + 1) / NUM_2 * NUM_2;
1250     int32_t dstYOffset = 0;
1251     int32_t dstUvOffset = dstYStride * dstHeight;
1252     dstStrides = {dstYStride, dstUvStride, dstYOffset, dstUvOffset};
1253 
1254 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1255     if (context == nullptr) {
1256         return;
1257     }
1258     if (dstType == AllocatorType::DMA_ALLOC) {
1259         auto sb = static_cast<SurfaceBuffer*>(context);
1260         if (sb == nullptr) {
1261             IMAGE_LOGE("get SurfaceBuffer failed");
1262             return;
1263         }
1264         OH_NativeBuffer_Planes *planes = nullptr;
1265         GSError retVal = sb->GetPlanesInfo(reinterpret_cast<void**>(&planes));
1266         if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
1267             IMAGE_LOGE("UpdateSdrYuvStrides Get planesInfo failed, retVal:%{public}d", retVal);
1268         } else if (planes->planeCount >= NUM_2) {
1269             int32_t pixelFmt = sb->GetFormat();
1270             GetYUVStrideInfo(pixelFmt, planes, dstStrides);
1271         }
1272     }
1273 #endif
1274 }
1275 
GetReusePixelRefCount(const std::shared_ptr<PixelMap> & reusePixelmap)1276 uint16_t ImageUtils::GetReusePixelRefCount(const std::shared_ptr<PixelMap> &reusePixelmap)
1277 {
1278 #if !defined(CROSS_PLATFORM)
1279     if (reusePixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
1280         return 0;
1281     }
1282     void* sbBuffer = reusePixelmap->GetFd();
1283     if (sbBuffer != nullptr) {
1284         OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(sbBuffer);
1285         uint16_t reusePixelRefCount = static_cast<uint16_t>(ref->GetSptrRefCount());
1286         return reusePixelRefCount;
1287     }
1288     return 0;
1289 #else
1290     return 0;
1291 #endif
1292 }
1293 
CanReusePixelMap(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1294 bool ImageUtils::CanReusePixelMap(ImagePlugin::DecodeContext& context, int width,
1295     int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1296 {
1297     if (reusePixelmap == nullptr) {
1298         IMAGE_LOGD("reusePixelmap is nullptr");
1299         return false;
1300     }
1301     bool cond = GetReusePixelRefCount(reusePixelmap) != 1;
1302     CHECK_ERROR_RETURN_RET_LOG(cond, false, "reusePixelmap reference count is not equal to 1");
1303     cond = ((width != reusePixelmap->GetWidth()) || (height != reusePixelmap->GetHeight()));
1304     CHECK_ERROR_RETURN_RET_LOG(cond, false, "The height or width of image is not equal to reusePixelmap");
1305     cond = ((reusePixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC) ||
1306         (context.allocatorType != AllocatorType::DMA_ALLOC));
1307     CHECK_ERROR_RETURN_RET_LOG(cond, false, "Image allocatortype is not DMA");
1308     return true;
1309 }
1310 
CanReusePixelMapHdr(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1311 bool ImageUtils::CanReusePixelMapHdr(ImagePlugin::DecodeContext& context, int width,
1312     int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1313 {
1314 #if !defined(CROSS_PLATFORM)
1315     if (!CanReusePixelMap(context, width, height, reusePixelmap)) {
1316         return false;
1317     }
1318     auto hdrPixelFormat = GRAPHIC_PIXEL_FMT_RGBA_1010102;
1319     if (context.photoDesiredPixelFormat == PixelFormat::YCBCR_P010) {
1320         hdrPixelFormat = GRAPHIC_PIXEL_FMT_YCBCR_P010;
1321     }
1322     SetContextHdr(context, hdrPixelFormat);
1323     bool cond = ((reusePixelmap->GetPixelFormat() != PixelFormat::RGBA_1010102) ||
1324         (context.info.pixelFormat != PixelFormat::RGBA_1010102));
1325     CHECK_ERROR_RETURN_RET_LOG(cond, false, "PixelFormat of Hdrimage is not equal to reusePixelmap");
1326     return true;
1327 #else
1328     return false;
1329 #endif
1330 }
1331 
IsReuseYUVFormat(PixelFormat format)1332 bool IsReuseYUVFormat(PixelFormat format)
1333 {
1334     return format == PixelFormat::NV12 || format == PixelFormat::NV21;
1335 }
1336 
1337 // Determine whether the reusePixelmap and decoding image are both YUV format.
IsReuseYUV(ImagePlugin::DecodeContext & context,const std::shared_ptr<PixelMap> & reusePixelmap)1338 bool ImageUtils::IsReuseYUV(ImagePlugin::DecodeContext& context, const std::shared_ptr<PixelMap> &reusePixelmap)
1339 {
1340     return IsReuseYUVFormat(reusePixelmap->GetPixelFormat()) && IsReuseYUVFormat(context.info.pixelFormat);
1341 }
1342 
IsReuseRGBFormat(PixelFormat format)1343 bool IsReuseRGBFormat(PixelFormat format)
1344 {
1345     return format == PixelFormat::RGBA_8888 || format == PixelFormat::BGRA_8888;
1346 }
1347 
1348 // Determine whether the reusePixelmap and decoding image are both RGB format.
IsReuseRGB(ImagePlugin::DecodeContext & context,const std::shared_ptr<PixelMap> & reusePixelmap)1349 bool ImageUtils::IsReuseRGB(ImagePlugin::DecodeContext& context, const std::shared_ptr<PixelMap> &reusePixelmap)
1350 {
1351     return IsReuseRGBFormat(reusePixelmap->GetPixelFormat()) && IsReuseRGBFormat(context.info.pixelFormat);
1352 }
1353 
CanReusePixelMapSdr(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1354 bool ImageUtils::CanReusePixelMapSdr(ImagePlugin::DecodeContext& context, int width,
1355     int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1356 {
1357     if (!CanReusePixelMap(context, width, height, reusePixelmap)) {
1358         return false;
1359     }
1360     bool cond = ((reusePixelmap->GetPixelFormat() == PixelFormat::RGBA_1010102) ||
1361         (context.info.pixelFormat == PixelFormat::RGBA_1010102));
1362     CHECK_ERROR_RETURN_RET_LOG(cond, false, "Sdr image is not RGBA 10bit");
1363     cond = (!IsReuseYUV(context, reusePixelmap) && !IsReuseRGB(context, reusePixelmap));
1364     CHECK_ERROR_RETURN_RET_LOG(cond, false, "PixelFormat of Sdrimage is not equal to reusePixelmap");
1365     return true;
1366 }
1367 
CanApplyMemForReusePixel(ImagePlugin::DecodeContext & context,const std::shared_ptr<PixelMap> & reusePixelmap)1368 bool CanApplyMemForReusePixel(ImagePlugin::DecodeContext& context,
1369     const std::shared_ptr<PixelMap> &reusePixelmap)
1370 {
1371 #if !defined(CROSS_PLATFORM)
1372     uint8_t *reusePixelBuffer = const_cast<uint8_t *>(reusePixelmap->GetPixels());
1373     int32_t err = ImageUtils::SurfaceBuffer_Reference(reusePixelmap->GetFd());
1374     bool cond = err != OHOS::GSERROR_OK;
1375     CHECK_ERROR_RETURN_RET_LOG(cond, false, "reusePixelmapBuffer Reference failed");
1376     ImageUtils::SetReuseContextBuffer(context, AllocatorType::DMA_ALLOC, reusePixelBuffer,
1377         reusePixelmap->GetCapacity(), reusePixelmap->GetFd());
1378     return true;
1379 #else
1380     return false;
1381 #endif
1382 }
1383 
IsSdrPixelMapReuseSuccess(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1384 bool ImageUtils::IsSdrPixelMapReuseSuccess(ImagePlugin::DecodeContext& context, int width,
1385     int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1386 {
1387 #if !defined(CROSS_PLATFORM)
1388     if (!CanReusePixelMapSdr(context, width, height, reusePixelmap)) {
1389         return false;
1390     }
1391     return CanApplyMemForReusePixel(context, reusePixelmap);
1392 #else
1393     return false;
1394 #endif
1395 }
1396 
IsHdrPixelMapReuseSuccess(ImagePlugin::DecodeContext & context,int width,int height,const std::shared_ptr<PixelMap> & reusePixelmap)1397 bool ImageUtils::IsHdrPixelMapReuseSuccess(ImagePlugin::DecodeContext& context, int width,
1398     int height, const std::shared_ptr<PixelMap> &reusePixelmap)
1399 {
1400 #if !defined(CROSS_PLATFORM)
1401     if (!CanReusePixelMapHdr(context, width, height, reusePixelmap)) {
1402         return false;
1403     }
1404     return CanApplyMemForReusePixel(context, reusePixelmap);
1405 #else
1406     return false;
1407 #endif
1408 }
1409 
SetContextHdr(ImagePlugin::DecodeContext & context,uint32_t format)1410 void ImageUtils::SetContextHdr(ImagePlugin::DecodeContext& context, uint32_t format)
1411 {
1412 #if !defined(CROSS_PLATFORM)
1413     context.info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
1414     if (format == GRAPHIC_PIXEL_FMT_RGBA_1010102) {
1415         context.pixelFormat = PixelFormat::RGBA_1010102;
1416         context.info.pixelFormat = PixelFormat::RGBA_1010102;
1417         context.grColorSpaceName = ColorManager::BT2020_HLG;
1418     } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
1419         context.pixelFormat = PixelFormat::YCBCR_P010;
1420         context.info.pixelFormat = PixelFormat::YCBCR_P010;
1421         context.grColorSpaceName = ColorManager::BT2020_HLG;
1422     }
1423 #endif
1424 }
1425 
SetReuseContextBuffer(ImagePlugin::DecodeContext & context,AllocatorType type,uint8_t * ptr,uint64_t count,void * fd)1426 void ImageUtils::SetReuseContextBuffer(ImagePlugin::DecodeContext& context,
1427     AllocatorType type, uint8_t* ptr, uint64_t count, void* fd)
1428 {
1429     context.allocatorType = type;
1430     context.freeFunc = nullptr;
1431     context.pixelsBuffer.buffer = ptr;
1432     context.pixelsBuffer.bufferSize = count;
1433     context.pixelsBuffer.context = fd;
1434 }
1435 
CheckRowDataSizeIsVaild(int32_t & rowDataSize,ImageInfo & imgInfo)1436 bool ImageUtils::CheckRowDataSizeIsVaild(int32_t &rowDataSize, ImageInfo &imgInfo)
1437 {
1438     int32_t bytesPerPixel = ImageUtils::GetPixelBytes(imgInfo.pixelFormat);
1439     if (bytesPerPixel == 0 || rowDataSize <=0 ||
1440         rowDataSize != ImageUtils::GetRowDataSizeByPixelFormat(imgInfo.size.width, imgInfo.pixelFormat)) {
1441         IMAGE_LOGE("[ImageUtils] RowDataSizeIsVaild: bytesPerPixel or rowDataSize:%{public}d", rowDataSize);
1442         return false;
1443     }
1444     return true;
1445 }
1446 
CheckBufferSizeIsVaild(int32_t & bufferSize,uint64_t & expectedBufferSize,AllocatorType & allocatorType)1447 bool ImageUtils::CheckBufferSizeIsVaild(int32_t &bufferSize, uint64_t &expectedBufferSize, AllocatorType &allocatorType)
1448 {
1449     if (bufferSize <= 0 ||
1450         expectedBufferSize > (allocatorType == AllocatorType::HEAP_ALLOC ? PIXEL_MAP_MAX_RAM_SIZE : INT_MAX) ||
1451         expectedBufferSize != static_cast<uint64_t>(bufferSize)) {
1452         IMAGE_LOGE("[ImageUtils] BufferSizeIsVaild: bufferSize invalid, expect:%{public}llu, actual:%{public}d",
1453             static_cast<unsigned long long>(expectedBufferSize), bufferSize);
1454         return false;
1455     }
1456     return true;
1457 }
1458 
GetAlignedNumber(int32_t & number,int32_t align)1459 bool ImageUtils::GetAlignedNumber(int32_t& number, int32_t align)
1460 {
1461     if (number < 0 || align <= 0) {
1462         return false;
1463     }
1464     int64_t res = number;
1465     res = (res + align - 1) / align * align;
1466     if (res > INT32_MAX) {
1467         return false;
1468     }
1469     number = static_cast<int32_t>(res);
1470     return true;
1471 }
1472 
GetRGBA1010102ColorR(uint32_t color)1473 uint16_t ImageUtils::GetRGBA1010102ColorR(uint32_t color)
1474 {
1475     return (color >> RGBA1010102_R_SHIFT) & RGBA1010102_RGB_MASK;
1476 }
1477 
GetRGBA1010102ColorG(uint32_t color)1478 uint16_t ImageUtils::GetRGBA1010102ColorG(uint32_t color)
1479 {
1480     return (color >> RGBA1010102_G_SHIFT) & RGBA1010102_RGB_MASK;
1481 }
1482 
GetRGBA1010102ColorB(uint32_t color)1483 uint16_t ImageUtils::GetRGBA1010102ColorB(uint32_t color)
1484 {
1485     return (color >> RGBA1010102_B_SHIFT) & RGBA1010102_RGB_MASK;
1486 }
1487 
GetRGBA1010102ColorA(uint32_t color)1488 uint16_t ImageUtils::GetRGBA1010102ColorA(uint32_t color)
1489 {
1490     return (color >> RGBA1010102_A_SHIFT) & RGBA1010102_ALPHA_MASK;
1491 }
1492 } // namespace Media
1493 } // namespace OHOS
1494