• 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 "pixel_map.h"
17 #ifdef EXT_PIXEL
18 #include "pixel_yuv_ext.h"
19 #endif
20 #include <charconv>
21 #include <chrono>
22 #include <iostream>
23 #include <unistd.h>
24 #if !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
25 #include <linux/dma-buf.h>
26 #endif
27 #include <sys/ioctl.h>
28 
29 #include "image_log.h"
30 #include "image_system_properties.h"
31 #include "image_trace.h"
32 #include "image_type_converter.h"
33 #include "image_utils.h"
34 #include "memory_manager.h"
35 #include "include/core/SkBitmap.h"
36 #include "include/core/SkCanvas.h"
37 #include "include/core/SkImage.h"
38 #include "hitrace_meter.h"
39 #include "media_errors.h"
40 #include "pixel_convert_adapter.h"
41 #include "pixel_map_utils.h"
42 #include "post_proc.h"
43 #include "parcel.h"
44 #include "pubdef.h"
45 #include "exif_metadata.h"
46 #include "image_mdk_common.h"
47 #include "pixel_yuv.h"
48 
49 #ifndef _WIN32
50 #include "securec.h"
51 #else
52 #include "memory.h"
53 #endif
54 
55 #ifdef IMAGE_PURGEABLE_PIXELMAP
56 #include "purgeable_resource_manager.h"
57 #endif
58 
59 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
60 #include <sys/mman.h>
61 #include "ashmem.h"
62 #include "buffer_handle_parcel.h"
63 #include "ipc_file_descriptor.h"
64 #include "surface_buffer.h"
65 #include "vpe_utils.h"
66 #include "v1_0/buffer_handle_meta_key_type.h"
67 #include "v1_0/cm_color_space.h"
68 #endif
69 
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
73 #include "libswscale/swscale.h"
74 #include "libavutil/opt.h"
75 #include "libavutil/imgutils.h"
76 #include "libavcodec/avcodec.h"
77 #ifdef __cplusplus
78 }
79 #endif
80 
81 #undef LOG_DOMAIN
82 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
83 
84 #undef LOG_TAG
85 #define LOG_TAG "PixelMap"
86 
87 namespace OHOS {
88 namespace Media {
89 using namespace std;
90 constexpr int32_t MAX_DIMENSION = INT32_MAX >> 2;
91 constexpr int8_t INVALID_ALPHA_INDEX = -1;
92 constexpr uint8_t ARGB_ALPHA_INDEX = 0;
93 constexpr uint8_t BGRA_ALPHA_INDEX = 3;
94 constexpr uint8_t ALPHA_BYTES = 1;
95 constexpr uint8_t BGRA_BYTES = 4;
96 constexpr uint8_t RGBA_F16_BYTES = 8;
97 constexpr uint8_t PER_PIXEL_LEN = 1;
98 constexpr uint32_t MAX_READ_COUNT = 2048;
99 
100 constexpr uint8_t FILL_NUMBER = 3;
101 constexpr uint8_t ALIGN_NUMBER = 4;
102 
103 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
104 static const uint8_t NUM_1 = 1;
105 #endif
106 static const uint8_t NUM_2 = 2;
107 static const uint8_t NUM_3 = 3;
108 static const uint8_t NUM_4 = 4;
109 static const uint8_t NUM_5 = 5;
110 static const uint8_t NUM_6 = 6;
111 static const uint8_t NUM_7 = 7;
112 static const uint8_t NUM_8 = 8;
113 
114 constexpr int32_t ANTIALIASING_SIZE = 350;
115 
116 std::atomic<uint32_t> PixelMap::currentId = 0;
117 
~PixelMap()118 PixelMap::~PixelMap()
119 {
120     IMAGE_LOGD("PixelMap::~PixelMap_id:%{public}d width:%{public}d height:%{public}d",
121         GetUniqueId(), imageInfo_.size.width, imageInfo_.size.height);
122     FreePixelMap();
123 }
124 
FreePixelMap()125 void PixelMap::FreePixelMap() __attribute__((no_sanitize("cfi")))
126 {
127     // remove PixelMap from purgeable LRU if it is purgeable PixelMap
128 #ifdef IMAGE_PURGEABLE_PIXELMAP
129     if (purgeableMemPtr_) {
130         PurgeableMem::PurgeableResourceManager::GetInstance().RemoveResource(purgeableMemPtr_);
131         purgeableMemPtr_.reset();
132         purgeableMemPtr_ = nullptr;
133     }
134 #endif
135 
136     if (!isUnMap_ && data_ == nullptr) {
137         return;
138     }
139 
140     if (freePixelMapProc_ != nullptr) {
141         freePixelMapProc_(data_, context_, pixelsSize_);
142     }
143 
144     switch (allocatorType_) {
145         case AllocatorType::HEAP_ALLOC: {
146             free(data_);
147             data_ = nullptr;
148             break;
149         }
150         case AllocatorType::CUSTOM_ALLOC: {
151             if (custFreePixelMap_ != nullptr) {
152                 custFreePixelMap_(data_, context_, pixelsSize_);
153             }
154             data_ = nullptr;
155             context_ = nullptr;
156             break;
157         }
158         case AllocatorType::SHARE_MEM_ALLOC: {
159             ReleaseSharedMemory(data_, context_, pixelsSize_);
160             data_ = nullptr;
161             context_ = nullptr;
162             break;
163         }
164         case AllocatorType::DMA_ALLOC: {
165 #if !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
166             ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer*>(context_));
167             data_ = nullptr;
168             context_ = nullptr;
169 #endif
170             break;
171         }
172         default: {
173             IMAGE_LOGE("unknown allocator type:[%{public}d].", allocatorType_);
174             return;
175         }
176     }
177 }
178 
ReleaseSharedMemory(void * addr,void * context,uint32_t size)179 void PixelMap::ReleaseSharedMemory(void *addr, void *context, uint32_t size)
180 {
181 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
182     int *fd = static_cast<int *>(context);
183     if (!isUnMap_ && addr != nullptr) {
184         ::munmap(addr, size);
185     }
186     if (fd != nullptr) {
187         ::close(*fd);
188         delete fd;
189     }
190 #endif
191 }
192 
SetFreePixelMapProc(CustomFreePixelMap func)193 void PixelMap::SetFreePixelMapProc(CustomFreePixelMap func)
194 {
195     freePixelMapProc_ = func;
196 }
197 
SetTransformered(bool isTransformered)198 void PixelMap::SetTransformered(bool isTransformered)
199 {
200     std::unique_lock<std::mutex> lock(*transformMutex_);
201     isTransformered_ = isTransformered;
202 }
203 
SetPixelsAddr(void * addr,void * context,uint32_t size,AllocatorType type,CustomFreePixelMap func)204 void PixelMap::SetPixelsAddr(void *addr, void *context, uint32_t size, AllocatorType type, CustomFreePixelMap func)
205 {
206     if (data_ != nullptr) {
207         IMAGE_LOGD("SetPixelsAddr release the existed data first");
208         FreePixelMap();
209     }
210     if (type == AllocatorType::SHARE_MEM_ALLOC && context == nullptr) {
211         IMAGE_LOGE("SetPixelsAddr error type %{public}d ", type);
212     }
213     data_ = static_cast<uint8_t *>(addr);
214     isUnMap_ = false;
215     unMapCount_ = 0;
216     context_ = context;
217     pixelsSize_ = size;
218     allocatorType_ = type;
219     custFreePixelMap_ = func;
220     if (type == AllocatorType::DMA_ALLOC && rowDataSize_ != 0) {
221         UpdateImageInfo();
222     }
223 }
224 
CheckPixelmap(std::unique_ptr<PixelMap> & pixelMap,ImageInfo & imageInfo)225 bool CheckPixelmap(std::unique_ptr<PixelMap> &pixelMap, ImageInfo &imageInfo)
226 {
227     if (pixelMap->SetImageInfo(imageInfo) != SUCCESS) {
228         IMAGE_LOGE("set image info failed");
229         return false;
230     }
231     int32_t bufferSize = pixelMap->GetByteCount();
232     if (bufferSize <= 0 || (pixelMap->GetAllocatorType() == AllocatorType::HEAP_ALLOC &&
233         bufferSize > PIXEL_MAP_MAX_RAM_SIZE)) {
234         IMAGE_LOGE("Invalid byte count");
235         return false;
236     }
237     return true;
238 }
239 
Create(const uint32_t * colors,uint32_t colorLength,const InitializationOptions & opts)240 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, const InitializationOptions &opts)
241 {
242     IMAGE_LOGD("PixelMap::Create1 enter");
243     return Create(colors, colorLength, 0, opts.size.width, opts);
244 }
245 
Create(const uint32_t * colors,uint32_t colorLength,int32_t offset,int32_t width,const InitializationOptions & opts)246 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, int32_t offset, int32_t width,
247                                       const InitializationOptions &opts)
248 {
249     IMAGE_LOGD("PixelMap::Create2 enter");
250     return Create(colors, colorLength, 0, opts.size.width, opts, true);
251 }
252 
Create(const uint32_t * colors,uint32_t colorLength,int32_t offset,int32_t width,const InitializationOptions & opts,bool useCustomFormat)253 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, int32_t offset, int32_t width,
254                                       const InitializationOptions &opts, bool useCustomFormat)
255 {
256     int errorCode;
257     BUILD_PARAM info;
258     info.offset_ = offset;
259     info.width_ = width;
260     info.flag_ = useCustomFormat;
261     return Create(colors, colorLength, info, opts, errorCode);
262 }
263 
PixelFormatToAVPixelFormat(const PixelFormat & pixelFormat)264 static AVPixelFormat PixelFormatToAVPixelFormat(const PixelFormat &pixelFormat)
265 {
266     auto formatSearch = PixelConvertAdapter::FFMPEG_PIXEL_FORMAT_MAP.find(pixelFormat);
267     return (formatSearch != PixelConvertAdapter::FFMPEG_PIXEL_FORMAT_MAP.end()) ?
268         formatSearch->second : AVPixelFormat::AV_PIX_FMT_NONE;
269 }
270 
IsYUV(const PixelFormat & format)271 bool IsYUV(const PixelFormat &format)
272 {
273     return format == PixelFormat::NV12 || format == PixelFormat::NV21 ||
274         format == PixelFormat::YCBCR_P010 || format == PixelFormat::YCRCB_P010;
275 }
276 
GetRGBxRowDataSize(const ImageInfo & info)277 int32_t PixelMap::GetRGBxRowDataSize(const ImageInfo& info)
278 {
279     if ((info.pixelFormat <= PixelFormat::UNKNOWN || info.pixelFormat >= PixelFormat::EXTERNAL_MAX) ||
280         IsYUV(info.pixelFormat)) {
281         IMAGE_LOGE("[ImageUtil]unsupported pixel format");
282         return -1;
283     }
284     int32_t pixelBytes = ImageUtils::GetPixelBytes(info.pixelFormat);
285     if (pixelBytes < 0) {
286         IMAGE_LOGE("[ImageUtil]get rgbx pixel bytes failed");
287         return -1;
288     }
289     return pixelBytes * info.size.width;
290 }
291 
GetRGBxByteCount(const ImageInfo & info)292 int32_t PixelMap::GetRGBxByteCount(const ImageInfo& info)
293 {
294     if (IsYUV(info.pixelFormat)) {
295         IMAGE_LOGE("[ImageUtil]unsupported pixel format");
296         return -1;
297     }
298     int32_t rowDataSize = GetRGBxRowDataSize(info);
299     if (rowDataSize < 0) {
300         IMAGE_LOGE("[ImageUtil]get rgbx row data size failed");
301         return -1;
302     }
303     return rowDataSize * info.size.height;
304 }
305 
GetYUVByteCount(const ImageInfo & info)306 int32_t PixelMap::GetYUVByteCount(const ImageInfo& info)
307 {
308     if (!IsYUV(info.pixelFormat)) {
309         IMAGE_LOGE("[ImageUtil]unsupported pixel format");
310         return -1;
311     }
312     if (info.size.width <= 0 || info.size.height <= 0) {
313         IMAGE_LOGE("[ImageUtil]image size error");
314         return -1;
315     }
316     AVPixelFormat avPixelFormat = PixelFormatToAVPixelFormat(info.pixelFormat);
317     if (avPixelFormat == AVPixelFormat::AV_PIX_FMT_NONE) {
318         IMAGE_LOGE("[ImageUtil]pixel format to ffmpeg pixel format failed");
319         return -1;
320     }
321     return av_image_get_buffer_size(avPixelFormat, info.size.width, info.size.height, 1);
322 }
323 
GetAllocatedByteCount(const ImageInfo & info)324 int32_t PixelMap::GetAllocatedByteCount(const ImageInfo& info)
325 {
326     if (IsYUV(info.pixelFormat)) {
327         return GetYUVByteCount(info);
328     } else {
329         return GetRGBxByteCount(info);
330     }
331 }
332 
UpdateYUVDataInfo(int32_t width,int32_t height,YUVDataInfo & yuvInfo)333 void UpdateYUVDataInfo(int32_t width, int32_t height, YUVDataInfo &yuvInfo)
334 {
335     yuvInfo.yWidth = static_cast<uint32_t>(width);
336     yuvInfo.yHeight = static_cast<uint32_t>(height);
337     yuvInfo.uvWidth = static_cast<uint32_t>((width + 1) / NUM_2);
338     yuvInfo.uvHeight = static_cast<uint32_t>((height + 1) / NUM_2);
339     yuvInfo.yStride = static_cast<uint32_t>(width);
340     yuvInfo.uvStride = static_cast<uint32_t>(((width + 1) / NUM_2) * NUM_2);
341     yuvInfo.uvOffset = static_cast<uint32_t>(width) * height;
342 }
343 
ChoosePixelmap(unique_ptr<PixelMap> & dstPixelMap,PixelFormat pixelFormat,int & errorCode)344 static bool ChoosePixelmap(unique_ptr<PixelMap> &dstPixelMap, PixelFormat pixelFormat, int &errorCode)
345 {
346     if (IsYUV(pixelFormat)) {
347 #ifdef EXT_PIXEL
348         dstPixelMap = make_unique<PixelYuvExt>();
349 #else
350         dstPixelMap = make_unique<PixelYuv>();
351 #endif
352     } else {
353         dstPixelMap = make_unique<PixelMap>();
354     }
355     if (dstPixelMap == nullptr) {
356         IMAGE_LOGE("[image]Create: make pixelmap failed!");
357         errorCode = IMAGE_RESULT_PLUGIN_REGISTER_FAILED;
358         return false;
359     }
360     return true;
361 }
362 
SetYUVDataInfoToPixelMap(unique_ptr<PixelMap> & dstPixelMap)363 static void SetYUVDataInfoToPixelMap(unique_ptr<PixelMap> &dstPixelMap)
364 {
365     if (IsYUV(dstPixelMap->GetPixelFormat())) {
366         YUVDataInfo yDatainfo;
367         UpdateYUVDataInfo(dstPixelMap->GetWidth(), dstPixelMap->GetHeight(), yDatainfo);
368         dstPixelMap->SetImageYUVInfo(yDatainfo);
369     }
370 }
371 
AllocPixelMapMemory(std::unique_ptr<AbsMemory> & dstMemory,int32_t & dstRowStride,const ImageInfo & dstImageInfo,bool useDMA)372 static int AllocPixelMapMemory(std::unique_ptr<AbsMemory> &dstMemory, int32_t &dstRowStride,
373     const ImageInfo &dstImageInfo, bool useDMA)
374 {
375     if (ImageUtils::CheckMulOverflow(dstImageInfo.size.width, dstImageInfo.size.height,
376                                      ImageUtils::GetPixelBytes(dstImageInfo.pixelFormat))) {
377         IMAGE_LOGE("[PixelMap]Create: pixelmap size overflow: width = %{public}d, height = %{public}d",
378                    dstImageInfo.size.width, dstImageInfo.size.height);
379         return IMAGE_RESULT_BAD_PARAMETER;
380     }
381     size_t bufferSize = static_cast<size_t>(dstImageInfo.size.width) * static_cast<size_t>(dstImageInfo.size.height) *
382         static_cast<size_t>(ImageUtils::GetPixelBytes(dstImageInfo.pixelFormat));
383     if (bufferSize > UINT_MAX) {
384         IMAGE_LOGE("[PixelMap]Create: pixelmap size too large: width = %{public}d, height = %{public}d",
385             dstImageInfo.size.width, dstImageInfo.size.height);
386         return IMAGE_RESULT_BAD_PARAMETER;
387     }
388 
389     MemoryData memoryData = {nullptr, bufferSize, "Create PixelMap", dstImageInfo.size, dstImageInfo.pixelFormat};
390     dstMemory = MemoryManager::CreateMemory(
391         ImageUtils::GetPixelMapAllocatorType(dstImageInfo.size, dstImageInfo.pixelFormat, useDMA), memoryData);
392     if (dstMemory == nullptr) {
393         IMAGE_LOGE("[PixelMap]Create: allocate memory failed");
394         return IMAGE_RESULT_MALLOC_ABNORMAL;
395     }
396 
397     dstRowStride = dstImageInfo.size.width * ImageUtils::GetPixelBytes(dstImageInfo.pixelFormat);
398 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
399     if (dstMemory->GetType() == AllocatorType::DMA_ALLOC) {
400         SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(dstMemory->extend.data);
401         dstRowStride = sbBuffer->GetStride();
402     }
403 #endif
404 
405     return IMAGE_RESULT_SUCCESS;
406 }
407 
408 // LCOV_EXCL_START
Create(const uint32_t * colors,uint32_t colorLength,BUILD_PARAM & info,const InitializationOptions & opts,int & errorCode)409 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, BUILD_PARAM &info,
410     const InitializationOptions &opts, int &errorCode)
411 {
412     int offset = info.offset_;
413     if (!CheckParams(colors, colorLength, offset, info.width_, opts)) {
414         errorCode = IMAGE_RESULT_BAD_PARAMETER;
415         return nullptr;
416     }
417 
418     unique_ptr<PixelMap> dstPixelMap;
419     if (!ChoosePixelmap(dstPixelMap, opts.pixelFormat, errorCode)) {
420         return nullptr;
421     }
422     PixelFormat format = PixelFormat::BGRA_8888;
423     if (info.flag_) {
424         format = ((opts.srcPixelFormat == PixelFormat::UNKNOWN) ? PixelFormat::BGRA_8888 : opts.srcPixelFormat);
425     }
426     ImageInfo srcImageInfo = MakeImageInfo(info.width_, opts.size.height, format, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
427     PixelFormat dstPixelFormat = opts.pixelFormat == PixelFormat::UNKNOWN ? PixelFormat::RGBA_8888 : opts.pixelFormat;
428     AlphaType dstAlphaType =
429         opts.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN ? AlphaType::IMAGE_ALPHA_TYPE_PREMUL : opts.alphaType;
430     dstAlphaType = ImageUtils::GetValidAlphaTypeByFormat(dstAlphaType, dstPixelFormat);
431     ImageInfo dstImageInfo = MakeImageInfo(opts.size.width, opts.size.height, dstPixelFormat, dstAlphaType);
432     if (!CheckPixelmap(dstPixelMap, dstImageInfo)) {
433         IMAGE_LOGE("[PixelMap]Create: check pixelmap failed!");
434         errorCode = IMAGE_RESULT_DATA_ABNORMAL;
435         return nullptr;
436     }
437 
438     std::unique_ptr<AbsMemory> dstMemory = nullptr;
439     int32_t dstRowStride = 0;
440     errorCode = AllocPixelMapMemory(dstMemory, dstRowStride, dstImageInfo, opts.useDMA);
441     if (errorCode != IMAGE_RESULT_SUCCESS) {
442         return nullptr;
443     }
444 
445     BufferInfo srcInfo = {const_cast<void*>(reinterpret_cast<const void*>(colors + offset)), opts.srcRowStride,
446         srcImageInfo};
447     BufferInfo dstInfo = {dstMemory->data.data, dstRowStride, dstImageInfo};
448     int32_t dstLength =
449         PixelConvert::PixelsConvert(srcInfo, dstInfo, colorLength, dstMemory->GetType() == AllocatorType::DMA_ALLOC);
450     if (dstLength < 0) {
451         IMAGE_LOGE("[PixelMap]Create: pixel convert failed.");
452         dstMemory->Release();
453         errorCode = IMAGE_RESULT_THIRDPART_SKIA_ERROR;
454         return nullptr;
455     }
456 
457     dstPixelMap->SetEditable(opts.editable);
458     dstPixelMap->SetPixelsAddr(dstMemory->data.data, dstMemory->extend.data, dstMemory->data.size, dstMemory->GetType(),
459         nullptr);
460     ImageUtils::DumpPixelMapIfDumpEnabled(dstPixelMap);
461     SetYUVDataInfoToPixelMap(dstPixelMap);
462     return dstPixelMap;
463 }
464 // LCOV_EXCL_STOP
465 
ReleaseBuffer(AllocatorType allocatorType,int fd,uint64_t dataSize,void ** buffer)466 void PixelMap::ReleaseBuffer(AllocatorType allocatorType, int fd, uint64_t dataSize, void **buffer)
467 {
468 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
469     if (allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
470         if (buffer != nullptr && *buffer != nullptr) {
471             ::munmap(*buffer, dataSize);
472             ::close(fd);
473         }
474         return;
475     }
476 #endif
477 
478     if (allocatorType == AllocatorType::HEAP_ALLOC) {
479         if (buffer != nullptr && *buffer != nullptr) {
480             free(*buffer);
481             *buffer = nullptr;
482         }
483         return;
484     }
485 }
486 
SetMemoryName(std::string pixelMapName)487 uint32_t PixelMap::SetMemoryName(std::string pixelMapName)
488 {
489 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
490     if (GetFd() == nullptr) {
491         IMAGE_LOGE("PixelMap null, set name failed");
492         return ERR_MEMORY_NOT_SUPPORT;
493     }
494 
495     AllocatorType allocatorType = GetAllocatorType();
496 
497     if (pixelMapName.size() <= 0 || pixelMapName.size() > DMA_BUF_NAME_LEN - 1) {
498         IMAGE_LOGE("name size not compare");
499         return COMMON_ERR_INVALID_PARAMETER;
500     }
501 
502     if (allocatorType == AllocatorType::DMA_ALLOC) {
503         SurfaceBuffer *sbBuffer = reinterpret_cast<SurfaceBuffer*>(GetFd());
504         int fd = sbBuffer->GetFileDescriptor();
505         if (fd < 0) {
506             return ERR_MEMORY_NOT_SUPPORT;
507         }
508         int ret = TEMP_FAILURE_RETRY(ioctl(fd, DMA_BUF_SET_NAME_A, pixelMapName.c_str()));
509         if (ret != 0) {
510             IMAGE_LOGE("set dma name failed");
511             return ERR_MEMORY_NOT_SUPPORT;
512         }
513         return SUCCESS;
514     }
515 
516     if (allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
517         int *fd = static_cast<int*>(GetFd());
518         if (*fd < 0) {
519             return ERR_MEMORY_NOT_SUPPORT;
520         }
521         int ret = TEMP_FAILURE_RETRY(ioctl(*fd, ASHMEM_SET_NAME, pixelMapName.c_str()));
522         if (ret != 0) {
523             IMAGE_LOGE("set ashmem name failed");
524             return ERR_MEMORY_NOT_SUPPORT;
525         }
526         return SUCCESS;
527     }
528     return ERR_MEMORY_NOT_SUPPORT;
529 #else
530     IMAGE_LOGE("[PixelMap] not support on crossed platform");
531     return ERR_MEMORY_NOT_SUPPORT;
532 #endif
533 }
534 
AllocSharedMemory(const uint64_t bufferSize,int & fd,uint32_t uniqueId)535 void *PixelMap::AllocSharedMemory(const uint64_t bufferSize, int &fd, uint32_t uniqueId)
536 {
537 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
538     std::string name = "PixelMap RawData, uniqueId: " + std::to_string(getpid()) + '_' + std::to_string(uniqueId);
539     fd = AshmemCreate(name.c_str(), bufferSize);
540     if (fd < 0) {
541         IMAGE_LOGE("AllocSharedMemory fd error");
542         return nullptr;
543     }
544     int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
545     if (result < 0) {
546         IMAGE_LOGE("AshmemSetProt error");
547         ::close(fd);
548         return nullptr;
549     }
550     void* ptr = ::mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
551     if (ptr == MAP_FAILED) {
552         IMAGE_LOGE("mmap error, errno: %{public}s, fd %{public}d, bufferSize %{public}lld",
553             strerror(errno), fd, (long long)bufferSize);
554         ::close(fd);
555         return nullptr;
556     }
557     return ptr;
558 #else
559     return malloc(bufferSize);
560 #endif
561 }
562 
CheckParams(const uint32_t * colors,uint32_t colorLength,int32_t offset,int32_t width,const InitializationOptions & opts)563 bool PixelMap::CheckParams(const uint32_t *colors, uint32_t colorLength, int32_t offset, int32_t width,
564     const InitializationOptions &opts)
565 {
566     if (colors == nullptr || colorLength <= 0) {
567         IMAGE_LOGE("colors invalid");
568         return false;
569     }
570     int32_t dstWidth = opts.size.width;
571     int32_t dstHeight = opts.size.height;
572     if (dstWidth <= 0 || dstHeight <= 0) {
573         IMAGE_LOGE("initial options size invalid");
574         return false;
575     }
576     if (width < dstWidth) {
577         IMAGE_LOGE("width: %{public}d must >= width: %{public}d", width, dstWidth);
578         return false;
579     }
580     if (width > MAX_DIMENSION) {
581         IMAGE_LOGE("stride %{public}d is out of range", width);
582         return false;
583     }
584     if (opts.srcRowStride != 0 && opts.srcRowStride < width * ImageUtils::GetPixelBytes(opts.srcPixelFormat)) {
585         IMAGE_LOGE("row stride %{public}d must be >= width (%{public}d) * row bytes (%{public}d)",
586             opts.srcRowStride, width, ImageUtils::GetPixelBytes(opts.srcPixelFormat));
587         return false;
588     }
589     int64_t lastLine = static_cast<int64_t>(dstHeight - 1) * width + offset;
590     if (offset < 0 || static_cast<int64_t>(offset) + dstWidth > colorLength || lastLine + dstWidth > colorLength) {
591         IMAGE_LOGE("colors length: %{public}u, offset: %{public}d, width: %{public}d  is invalid",
592             colorLength, offset, width);
593         return false;
594     }
595     return true;
596 }
597 
598 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
InitYuvDataOutInfo(SurfaceBuffer * surfaceBuffer,const ImageInfo & info,YUVDataInfo & yuvInfo)599 bool InitYuvDataOutInfo(SurfaceBuffer* surfaceBuffer, const ImageInfo &info, YUVDataInfo &yuvInfo)
600 {
601     if (surfaceBuffer == nullptr) {
602         IMAGE_LOGE("SurfaceBuffer object is null");
603         return false;
604     }
605     OH_NativeBuffer_Planes *planes = nullptr;
606     GSError retVal = surfaceBuffer->GetPlanesInfo(reinterpret_cast<void**>(&planes));
607     if (retVal != OHOS::GSERROR_OK || planes == nullptr || planes->planeCount < NUM_2) {
608         IMAGE_LOGE("InitYuvDataOutInfo failed");
609         return false;
610     }
611     uint32_t uvPlaneOffset = (info.pixelFormat == PixelFormat::NV12 ||
612         info.pixelFormat == PixelFormat::YCBCR_P010) ? NUM_1 : NUM_2;
613     yuvInfo.imageSize = info.size;
614     yuvInfo.yWidth = info.size.width;
615     yuvInfo.yHeight = info.size.height;
616     yuvInfo.uvWidth = static_cast<uint32_t>((info.size.width + NUM_1) / NUM_2);
617     yuvInfo.uvHeight = static_cast<uint32_t>((info.size.height + NUM_1) / NUM_2);
618     if (info.pixelFormat == PixelFormat::YCBCR_P010 || info.pixelFormat == PixelFormat::YCRCB_P010) {
619         yuvInfo.yStride = planes->planes[0].columnStride / NUM_2;
620         yuvInfo.uvStride = planes->planes[uvPlaneOffset].columnStride / NUM_2;
621         yuvInfo.yOffset = planes->planes[0].offset / NUM_2;
622         yuvInfo.uvOffset = planes->planes[uvPlaneOffset].offset / NUM_2;
623     } else {
624         yuvInfo.yStride = planes->planes[0].columnStride;
625         yuvInfo.uvStride = planes->planes[uvPlaneOffset].columnStride;
626         yuvInfo.yOffset = planes->planes[0].offset;
627         yuvInfo.uvOffset = planes->planes[uvPlaneOffset].offset;
628     }
629     return true;
630 }
631 #endif
632 
CheckPixelMap(unique_ptr<PixelMap> & dstPixelMap,const InitializationOptions & opts)633 static bool CheckPixelMap(unique_ptr<PixelMap>& dstPixelMap, const InitializationOptions &opts)
634 {
635     if (IsYUV(opts.pixelFormat)) {
636 #ifdef EXT_PIXEL
637         dstPixelMap = std::make_unique<PixelYuvExt>();
638 #else
639         dstPixelMap = std::make_unique<PixelYuv>();
640 #endif
641     } else {
642         dstPixelMap = make_unique<PixelMap>();
643     }
644     if (dstPixelMap == nullptr) {
645         IMAGE_LOGE("create pixelMap pointer fail");
646         return false;
647     }
648     return true;
649 }
650 
651 // LCOV_EXCL_START
Create(const InitializationOptions & opts)652 unique_ptr<PixelMap> PixelMap::Create(const InitializationOptions &opts)
653 {
654     unique_ptr<PixelMap> dstPixelMap;
655     if (!CheckPixelMap(dstPixelMap, opts)) {
656         return nullptr;
657     }
658     PixelFormat dstPixelFormat = (opts.pixelFormat == PixelFormat::UNKNOWN ? PixelFormat::RGBA_8888 : opts.pixelFormat);
659     AlphaType dstAlphaType =
660         (opts.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) ? AlphaType::IMAGE_ALPHA_TYPE_PREMUL : opts.alphaType;
661     dstAlphaType = ImageUtils::GetValidAlphaTypeByFormat(dstAlphaType, dstPixelFormat);
662     ImageInfo dstImageInfo = MakeImageInfo(opts.size.width, opts.size.height, dstPixelFormat, dstAlphaType);
663     if (dstPixelMap->SetImageInfo(dstImageInfo) != SUCCESS) {
664         IMAGE_LOGE("set image info failed");
665         return nullptr;
666     }
667 
668     std::unique_ptr<AbsMemory> dstMemory = nullptr;
669     int32_t dstRowStride = 0;
670     int errorCode = AllocPixelMapMemory(dstMemory, dstRowStride, dstImageInfo, opts.useDMA);
671     if (errorCode != IMAGE_RESULT_SUCCESS) {
672         return nullptr;
673     }
674     // update alpha opaque
675     UpdatePixelsAlpha(dstImageInfo.alphaType, dstImageInfo.pixelFormat,
676                       static_cast<uint8_t *>(dstMemory->data.data), *dstPixelMap.get());
677     dstPixelMap->SetEditable(opts.editable);
678     dstPixelMap->SetPixelsAddr(dstMemory->data.data, dstMemory->extend.data, dstMemory->data.size, dstMemory->GetType(),
679         nullptr);
680     ImageUtils::DumpPixelMapIfDumpEnabled(dstPixelMap);
681     if (IsYUV(opts.pixelFormat)) {
682         if (dstPixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
683             YUVDataInfo yuvDatainfo;
684 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
685             if (!InitYuvDataOutInfo(reinterpret_cast<SurfaceBuffer*>(dstMemory->extend.data),
686                 dstImageInfo, yuvDatainfo)) {
687                 return nullptr;
688             }
689 #endif
690             dstPixelMap->SetImageYUVInfo(yuvDatainfo);
691         } else {
692             SetYUVDataInfoToPixelMap(dstPixelMap);
693         }
694     }
695     return dstPixelMap;
696 }
697 // LCOV_EXCL_STOP
698 
UpdatePixelsAlpha(const AlphaType & alphaType,const PixelFormat & pixelFormat,uint8_t * dstPixels,PixelMap & dstPixelMap)699 void PixelMap::UpdatePixelsAlpha(const AlphaType &alphaType, const PixelFormat &pixelFormat, uint8_t *dstPixels,
700                                  PixelMap &dstPixelMap)
701 {
702     if (dstPixels == nullptr) {
703         IMAGE_LOGE("UpdatePixelsAlpha invalid input parameter: dstPixels is null");
704         return;
705     }
706 
707     if (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
708         int8_t alphaIndex = -1;
709         if (pixelFormat == PixelFormat::RGBA_8888 || pixelFormat == PixelFormat::BGRA_8888) {
710             alphaIndex = BGRA_ALPHA_INDEX;
711         } else if (pixelFormat == PixelFormat::ARGB_8888) {
712             alphaIndex = 0;
713         }
714         if (alphaIndex != -1) {
715             uint8_t pixelBytes = dstPixelMap.GetPixelBytes();
716             int32_t bufferSize = dstPixelMap.GetByteCount();
717             if (bufferSize <= 0) {
718                 IMAGE_LOGE("UpdatePixelsAlpha invalid byte count: %{public}d", bufferSize);
719                 return;
720             }
721             uint32_t uBufferSize = static_cast<uint32_t>(bufferSize);
722             for (uint32_t i = alphaIndex; i < uBufferSize; i += pixelBytes) {
723                 dstPixels[i] = ALPHA_OPAQUE;
724             }
725         }
726     }
727 }
728 
BuildPixelMap(unique_ptr<PixelMap> & dstPixelMap,const CropValue & cropType,ImageInfo & dstImageInfo,const Rect & sRect,const ImageInfo & srcImageInfo)729 static int32_t BuildPixelMap(unique_ptr<PixelMap> &dstPixelMap, const CropValue &cropType,
730     ImageInfo &dstImageInfo, const Rect &sRect, const ImageInfo &srcImageInfo)
731 {
732     dstPixelMap = make_unique<PixelMap>();
733     if (dstPixelMap == nullptr) {
734         IMAGE_LOGE("create pixelmap pointer fail");
735         return IMAGE_RESULT_PLUGIN_REGISTER_FAILED;
736     }
737 
738     if (cropType == CropValue::VALID) {
739         dstImageInfo.size.width = sRect.width;
740         dstImageInfo.size.height = sRect.height;
741     } else {
742         dstImageInfo.size = srcImageInfo.size;
743     }
744     if (dstPixelMap->SetImageInfo(dstImageInfo) != SUCCESS) {
745         return IMAGE_RESULT_DATA_ABNORMAL;
746     }
747     return SUCCESS;
748 }
749 
Create(PixelMap & source,const InitializationOptions & opts)750 unique_ptr<PixelMap> PixelMap::Create(PixelMap &source, const InitializationOptions &opts)
751 {
752     IMAGE_LOGD("PixelMap::Create4 enter");
753     Rect rect;
754     return Create(source, rect, opts);
755 }
756 
Create(PixelMap & source,const Rect & srcRect,const InitializationOptions & opts)757 unique_ptr<PixelMap> PixelMap::Create(PixelMap &source, const Rect &srcRect, const InitializationOptions &opts)
758 {
759     int error;
760     return Create(source, srcRect, opts, error);
761 }
762 
763 // LCOV_EXCL_START
Create(PixelMap & source,const Rect & srcRect,const InitializationOptions & opts,int32_t & errorCode)764 unique_ptr<PixelMap> PixelMap::Create(PixelMap &source, const Rect &srcRect, const InitializationOptions &opts,
765     int32_t &errorCode)
766 {
767     IMAGE_LOGD("PixelMap::Create5 enter");
768     ImageInfo srcImageInfo;
769     source.GetImageInfo(srcImageInfo);
770     PostProc postProc;
771     Rect sRect = srcRect;
772     CropValue cropType = PostProc::ValidCropValue(sRect, srcImageInfo.size);
773     if (cropType == CropValue::INVALID) {
774         IMAGE_LOGE("src crop range is invalid");
775         errorCode = IMAGE_RESULT_DECODE_FAILED;
776         return nullptr;
777     }
778     ImageInfo dstImageInfo;
779     InitDstImageInfo(opts, srcImageInfo, dstImageInfo);
780     Size targetSize = dstImageInfo.size;
781     // use source if match
782     bool isHasConvert = postProc.HasPixelConvert(srcImageInfo, dstImageInfo);
783     if (opts.useSourceIfMatch && !source.IsEditable() && !opts.editable && (cropType == CropValue::NOCROP) &&
784         !isHasConvert && IsSameSize(srcImageInfo.size, dstImageInfo.size)) {
785         source.useSourceAsResponse_ = true;
786         return unique_ptr<PixelMap>(&source);
787     }
788     unique_ptr<PixelMap> dstPixelMap = nullptr;
789     if ((errorCode = BuildPixelMap(dstPixelMap, cropType, dstImageInfo, sRect, srcImageInfo)) != SUCCESS) {
790         return nullptr;
791     }
792     // dst pixelmap is source crop and convert pixelmap
793     if ((cropType == CropValue::VALID) || isHasConvert) {
794         if (!SourceCropAndConvert(source, srcImageInfo, dstImageInfo, sRect, *dstPixelMap.get())) {
795             return nullptr;
796         }
797     } else {
798         // only maybe size changed, copy source as scale operation
799         if (!CopyPixelMap(source, *dstPixelMap.get(), errorCode)) {
800             return nullptr;
801         }
802     }
803     if (!ScalePixelMap(targetSize, dstImageInfo.size, opts.scaleMode, *dstPixelMap.get())) {
804         return nullptr;
805     }
806     dstPixelMap->SetEditable(opts.editable);
807     ImageUtils::DumpPixelMapIfDumpEnabled(dstPixelMap);
808     return dstPixelMap;
809 }
810 // LCOV_EXCL_STOP
811 
SourceCropAndConvert(PixelMap & source,const ImageInfo & srcImageInfo,const ImageInfo & dstImageInfo,const Rect & srcRect,PixelMap & dstPixelMap)812 bool PixelMap::SourceCropAndConvert(PixelMap &source, const ImageInfo &srcImageInfo, const ImageInfo &dstImageInfo,
813     const Rect &srcRect, PixelMap &dstPixelMap)
814 {
815     int32_t bufferSize = dstPixelMap.GetByteCount();
816     if (bufferSize <= 0 || (source.GetAllocatorType() == AllocatorType::HEAP_ALLOC &&
817         bufferSize > PIXEL_MAP_MAX_RAM_SIZE)) {
818         IMAGE_LOGE("SourceCropAndConvert  parameter bufferSize:[%{public}d] error.", bufferSize);
819         return false;
820     }
821     size_t uBufferSize = static_cast<size_t>(bufferSize);
822     int fd = 0;
823     void *dstPixels = nullptr;
824     if (source.GetAllocatorType() == AllocatorType::SHARE_MEM_ALLOC) {
825         dstPixels = AllocSharedMemory(uBufferSize, fd, dstPixelMap.GetUniqueId());
826     } else {
827         dstPixels = malloc(uBufferSize);
828     }
829     if (dstPixels == nullptr) {
830         IMAGE_LOGE("source crop allocate memory fail allocatetype: %{public}d ", source.GetAllocatorType());
831         return false;
832     }
833     if (memset_s(dstPixels, uBufferSize, 0, uBufferSize) != EOK) {
834         IMAGE_LOGE("dstPixels memset_s failed.");
835     }
836     Position srcPosition { srcRect.left, srcRect.top };
837     if (!PixelConvertAdapter::ReadPixelsConvert(source.GetPixels(), srcPosition, source.GetRowStride(), srcImageInfo,
838         dstPixels, dstPixelMap.GetRowStride(), dstImageInfo)) {
839         IMAGE_LOGE("pixel convert in adapter failed.");
840         ReleaseBuffer(fd > 0 ? AllocatorType::SHARE_MEM_ALLOC : AllocatorType::HEAP_ALLOC, fd, uBufferSize, &dstPixels);
841         return false;
842     }
843 
844     if (fd <= 0) {
845         dstPixelMap.SetPixelsAddr(dstPixels, nullptr, uBufferSize, AllocatorType::HEAP_ALLOC, nullptr);
846         return true;
847     }
848 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
849     void *fdBuffer = new int32_t();
850     *static_cast<int32_t *>(fdBuffer) = fd;
851     dstPixelMap.SetPixelsAddr(dstPixels, fdBuffer, uBufferSize, AllocatorType::SHARE_MEM_ALLOC, nullptr);
852 #else
853     dstPixelMap.SetPixelsAddr(dstPixels, nullptr, uBufferSize, AllocatorType::HEAP_ALLOC, nullptr);
854 #endif
855     return true;
856 }
857 
ScalePixelMap(const Size & targetSize,const Size & dstSize,const ScaleMode & scaleMode,PixelMap & dstPixelMap)858 bool PixelMap::ScalePixelMap(const Size &targetSize, const Size &dstSize, const ScaleMode &scaleMode,
859                              PixelMap &dstPixelMap)
860 {
861     if (dstSize.width == targetSize.width && dstSize.height == targetSize.height) {
862         return true;
863     }
864     PostProc postProc;
865     if (scaleMode == ScaleMode::FIT_TARGET_SIZE) {
866         if (!postProc.ScalePixelMap(targetSize, dstPixelMap)) {
867             IMAGE_LOGE("scale FIT_TARGET_SIZE fail");
868             return false;
869         }
870     }
871     if (scaleMode == ScaleMode::CENTER_CROP) {
872         if (!postProc.CenterScale(targetSize, dstPixelMap)) {
873             IMAGE_LOGE("scale CENTER_CROP fail");
874             return false;
875         }
876     }
877     return true;
878 }
879 
InitDstImageInfo(const InitializationOptions & opts,const ImageInfo & srcImageInfo,ImageInfo & dstImageInfo)880 void PixelMap::InitDstImageInfo(const InitializationOptions &opts, const ImageInfo &srcImageInfo,
881                                 ImageInfo &dstImageInfo)
882 {
883     dstImageInfo.size = opts.size;
884     if (dstImageInfo.size.width == 0 && dstImageInfo.size.height == 0) {
885         dstImageInfo.size = srcImageInfo.size;
886     }
887     dstImageInfo.pixelFormat = opts.pixelFormat;
888     if (dstImageInfo.pixelFormat == PixelFormat::UNKNOWN) {
889         dstImageInfo.pixelFormat = srcImageInfo.pixelFormat;
890     }
891     dstImageInfo.alphaType = opts.alphaType;
892     if (dstImageInfo.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
893         dstImageInfo.alphaType = srcImageInfo.alphaType;
894     }
895 }
896 
CopyPixMapToDst(PixelMap & source,void * & dstPixels,int & fd,uint32_t bufferSize)897 bool PixelMap::CopyPixMapToDst(PixelMap &source, void* &dstPixels, int &fd, uint32_t bufferSize)
898 {
899     if (source.GetAllocatorType() == AllocatorType::DMA_ALLOC) {
900         ImageInfo imageInfo;
901         source.GetImageInfo(imageInfo);
902         for (int i = 0; i < imageInfo.size.height; ++i) {
903             errno_t ret = memcpy_s(dstPixels, source.GetRowBytes(),
904                                    source.GetPixels() + i * source.GetRowStride(), source.GetRowBytes());
905             if (ret != 0) {
906                 IMAGE_LOGE("copy source memory size %{public}u fail", bufferSize);
907                 return false;
908             }
909             // Move the destination buffer pointer to the next row
910             dstPixels = reinterpret_cast<uint8_t *>(dstPixels) + source.GetRowStride();
911         }
912     } else {
913         if (memcpy_s(dstPixels, bufferSize, source.GetPixels(), bufferSize) != 0) {
914             IMAGE_LOGE("copy source memory size %{public}u fail", bufferSize);
915             return false;
916         }
917     }
918     return true;
919 }
920 
CopyPixelMap(PixelMap & source,PixelMap & dstPixelMap)921 bool PixelMap::CopyPixelMap(PixelMap &source, PixelMap &dstPixelMap)
922 {
923     int32_t error;
924     return CopyPixelMap(source, dstPixelMap, error);
925 }
926 
SetDstPixelMapInfo(PixelMap & source,PixelMap & dstPixelMap,void * dstPixels,uint32_t dstPixelsSize,unique_ptr<AbsMemory> & memory)927 static void SetDstPixelMapInfo(PixelMap &source, PixelMap &dstPixelMap, void* dstPixels, uint32_t dstPixelsSize,
928     unique_ptr<AbsMemory>& memory)
929 {
930     // "memory" is used for SHARE_MEM_ALLOC and DMA_ALLOC type, dstPixels is used for others.
931     AllocatorType sourceType = source.GetAllocatorType();
932     if (sourceType == AllocatorType::SHARE_MEM_ALLOC || sourceType == AllocatorType::DMA_ALLOC) {
933         dstPixelMap.SetPixelsAddr(dstPixels, memory->extend.data, memory->data.size, sourceType, nullptr);
934         if (source.GetAllocatorType() == AllocatorType::DMA_ALLOC && source.IsHdr()) {
935 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
936             sptr<SurfaceBuffer> sourceSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (source.GetFd()));
937             sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (dstPixelMap.GetFd()));
938             VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
939 #endif
940         }
941     } else {
942         dstPixelMap.SetPixelsAddr(dstPixels, nullptr, dstPixelsSize, AllocatorType::HEAP_ALLOC, nullptr);
943     }
944 #ifdef IMAGE_COLORSPACE_FLAG
945     OHOS::ColorManager::ColorSpace colorspace = source.InnerGetGrColorSpace();
946     dstPixelMap.InnerSetColorSpace(colorspace);
947 #endif
948 }
949 
CopyPixelMap(PixelMap & source,PixelMap & dstPixelMap,int32_t & error)950 bool PixelMap::CopyPixelMap(PixelMap &source, PixelMap &dstPixelMap, int32_t &error)
951 {
952     if (source.GetPixels() == nullptr) {
953         IMAGE_LOGE("source pixelMap data invalid");
954         error = IMAGE_RESULT_GET_DATA_ABNORMAL;
955         return false;
956     }
957 
958     int32_t bufferSize = source.GetByteCount();
959     if (bufferSize <= 0 || (source.GetAllocatorType() == AllocatorType::HEAP_ALLOC &&
960         bufferSize > PIXEL_MAP_MAX_RAM_SIZE)) {
961         IMAGE_LOGE("CopyPixelMap parameter bufferSize:[%{public}d] error.", bufferSize);
962         error = IMAGE_RESULT_DATA_ABNORMAL;
963         return false;
964     }
965     size_t uBufferSize = static_cast<size_t>(bufferSize);
966     int fd = -1;
967     void *dstPixels = nullptr;
968     unique_ptr<AbsMemory> memory;
969     AllocatorType sourceType = source.GetAllocatorType();
970     if (sourceType == AllocatorType::SHARE_MEM_ALLOC || sourceType == AllocatorType::DMA_ALLOC) {
971         ImageInfo dstImageInfo;
972         dstPixelMap.GetImageInfo(dstImageInfo);
973         MemoryData memoryData = {nullptr, uBufferSize, "Copy ImageData", dstImageInfo.size, dstImageInfo.pixelFormat};
974         memory = MemoryManager::CreateMemory(source.GetAllocatorType(), memoryData);
975         if (memory == nullptr) {
976             return false;
977         }
978         dstPixels = memory->data.data;
979     } else {
980         dstPixels = malloc(uBufferSize);
981     }
982     if (dstPixels == nullptr) {
983         IMAGE_LOGE("source crop allocate memory fail allocatetype: %{public}d ", source.GetAllocatorType());
984         error = IMAGE_RESULT_MALLOC_ABNORMAL;
985         return false;
986     }
987     void *tmpDstPixels = dstPixels;
988     if (!CopyPixMapToDst(source, tmpDstPixels, fd, uBufferSize)) {
989         if (sourceType == AllocatorType::SHARE_MEM_ALLOC || sourceType == AllocatorType::DMA_ALLOC) {
990             memory->Release();
991         } else {
992             ReleaseBuffer(AllocatorType::HEAP_ALLOC, fd, uBufferSize, &dstPixels);
993         }
994         error = IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL;
995         return false;
996     }
997     SetDstPixelMapInfo(source, dstPixelMap, dstPixels, uBufferSize, memory);
998     return true;
999 }
1000 
IsSameSize(const Size & src,const Size & dst)1001 bool PixelMap::IsSameSize(const Size &src, const Size &dst)
1002 {
1003     return (src.width == dst.width) && (src.height == dst.height);
1004 }
1005 
GetPixelFormatDetail(const PixelFormat format)1006 bool PixelMap::GetPixelFormatDetail(const PixelFormat format)
1007 {
1008     switch (format) {
1009         case PixelFormat::RGBA_8888: {
1010             pixelBytes_ = ARGB_8888_BYTES;
1011             colorProc_ = RGBA8888ToARGB;
1012             break;
1013         }
1014         case PixelFormat::RGBA_1010102: {
1015             pixelBytes_ = ARGB_8888_BYTES;
1016             break;
1017         }
1018         case PixelFormat::BGRA_8888: {
1019             pixelBytes_ = ARGB_8888_BYTES;
1020             colorProc_ = BGRA8888ToARGB;
1021             break;
1022         }
1023         case PixelFormat::ARGB_8888: {
1024             pixelBytes_ = ARGB_8888_BYTES;
1025             colorProc_ = ARGB8888ToARGB;
1026             break;
1027         }
1028         case PixelFormat::ALPHA_8: {
1029             pixelBytes_ = ALPHA_8_BYTES;
1030             colorProc_ = ALPHA8ToARGB;
1031             break;
1032         }
1033         case PixelFormat::RGB_565: {
1034             pixelBytes_ = RGB_565_BYTES;
1035             colorProc_ = RGB565ToARGB;
1036             break;
1037         }
1038         case PixelFormat::RGB_888: {
1039             pixelBytes_ = RGB_888_BYTES;
1040             colorProc_ = RGB888ToARGB;
1041             break;
1042         }
1043         case PixelFormat::NV12:
1044         case PixelFormat::NV21: {
1045             pixelBytes_ = YUV420_BYTES;
1046             break;
1047         }
1048         case PixelFormat::YCBCR_P010:
1049         case PixelFormat::YCRCB_P010: {
1050             pixelBytes_ = YUV420_P010_BYTES;
1051             break;
1052         }
1053         case PixelFormat::CMYK:
1054             pixelBytes_ = ARGB_8888_BYTES;
1055             break;
1056         case PixelFormat::RGBA_F16:
1057             pixelBytes_ = BGRA_F16_BYTES;
1058             break;
1059         case PixelFormat::ASTC_4x4:
1060         case PixelFormat::ASTC_6x6:
1061         case PixelFormat::ASTC_8x8:
1062             pixelBytes_ = ASTC_4x4_BYTES;
1063             break;
1064         default: {
1065             IMAGE_LOGE("pixel format:[%{public}d] not supported.", format);
1066             return false;
1067         }
1068     }
1069     return true;
1070 }
1071 
SetRowStride(uint32_t stride)1072 void PixelMap::SetRowStride(uint32_t stride)
1073 {
1074     rowStride_ = static_cast<int32_t>(stride);
1075 }
1076 
UpdateImageInfo()1077 void PixelMap::UpdateImageInfo()
1078 {
1079     SetImageInfo(imageInfo_, true);
1080 }
1081 
SetImageInfo(ImageInfo & info)1082 uint32_t PixelMap::SetImageInfo(ImageInfo &info)
1083 {
1084     return SetImageInfo(info, false);
1085 }
1086 
SetRowDataSizeForImageInfo(ImageInfo info)1087 uint32_t PixelMap::SetRowDataSizeForImageInfo(ImageInfo info)
1088 {
1089     rowDataSize_ = ImageUtils::GetRowDataSizeByPixelFormat(info.size.width, info.pixelFormat);
1090     if (rowDataSize_ <= 0) {
1091         IMAGE_LOGE("set imageInfo failed, rowDataSize_ invalid");
1092         return rowDataSize_ < 0 ? ERR_IMAGE_TOO_LARGE : ERR_IMAGE_DATA_ABNORMAL;
1093     }
1094 
1095     if (info.pixelFormat == PixelFormat::ALPHA_8) {
1096         SetRowStride(rowDataSize_);
1097         IMAGE_LOGI("ALPHA_8 rowDataSize_ %{public}d.", rowDataSize_);
1098     } else if (!ImageUtils::IsAstc(info.pixelFormat)) {
1099 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1100         if (allocatorType_ == AllocatorType::DMA_ALLOC) {
1101             if (context_ == nullptr) {
1102                 IMAGE_LOGE("set imageInfo failed, context_ is null");
1103                 return ERR_IMAGE_DATA_ABNORMAL;
1104             }
1105             SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(context_);
1106             SetRowStride(sbBuffer->GetStride());
1107         } else {
1108             SetRowStride(rowDataSize_);
1109         }
1110 #else
1111         SetRowStride(rowDataSize_);
1112 #endif
1113     }
1114     return SUCCESS;
1115 }
1116 
SetImageInfo(ImageInfo & info,bool isReused)1117 uint32_t PixelMap::SetImageInfo(ImageInfo &info, bool isReused)
1118 {
1119     if (info.size.width <= 0 || info.size.height <= 0) {
1120         IMAGE_LOGE("pixel map width or height invalid.");
1121         return ERR_IMAGE_DATA_ABNORMAL;
1122     }
1123 
1124     if (!GetPixelFormatDetail(info.pixelFormat)) {
1125         return ERR_IMAGE_DATA_UNSUPPORT;
1126     }
1127     if (pixelBytes_ <= 0) {
1128         ResetPixelMap();
1129         IMAGE_LOGE("pixel map bytes is invalid.");
1130         return ERR_IMAGE_DATA_ABNORMAL;
1131     }
1132 
1133     uint32_t ret = SetRowDataSizeForImageInfo(info);
1134     if (ret != SUCCESS) {
1135         IMAGE_LOGE("pixel map set rowDataSize error.");
1136         return ret;
1137     }
1138     if (static_cast<uint64_t>(rowDataSize_) * static_cast<uint64_t>(info.size.height) >
1139         (allocatorType_ == AllocatorType::HEAP_ALLOC ? PIXEL_MAP_MAX_RAM_SIZE : INT_MAX)) {
1140         ResetPixelMap();
1141         IMAGE_LOGE("pixel map size (byte count) out of range.");
1142         return ERR_IMAGE_TOO_LARGE;
1143     }
1144 
1145     if (!isReused) {
1146         FreePixelMap();
1147     }
1148     imageInfo_ = info;
1149     return SUCCESS;
1150 }
1151 
GetPixel8(int32_t x,int32_t y)1152 const uint8_t *PixelMap::GetPixel8(int32_t x, int32_t y)
1153 {
1154     if (!CheckValidParam(x, y) || (pixelBytes_ != ALPHA_8_BYTES)) {
1155         IMAGE_LOGE("get addr8 pixel position:(%{public}d, %{public}d) pixel bytes:%{public}d invalid.", x, y,
1156             pixelBytes_);
1157         return nullptr;
1158     }
1159 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1160     return (data_ + y * rowStride_ + x);
1161 #else
1162     return (data_ + y * rowDataSize_  + x);
1163 #endif
1164 }
1165 
GetPixel16(int32_t x,int32_t y)1166 const uint16_t *PixelMap::GetPixel16(int32_t x, int32_t y)
1167 {
1168     if (!CheckValidParam(x, y) || (pixelBytes_ != RGB_565_BYTES)) {
1169         IMAGE_LOGE("get addr16 pixel position:(%{public}d, %{public}d) pixel bytes:%{public}d invalid.", x, y,
1170             pixelBytes_);
1171         return nullptr;
1172     }
1173     // convert uint8_t* to uint16_t*
1174 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1175     return reinterpret_cast<uint16_t *>(data_ + y * rowStride_ + (static_cast<uint32_t>(x) << RGB_565_SHIFT));
1176 #else
1177     return reinterpret_cast<uint16_t *>(data_ + y * rowDataSize_ + (static_cast<uint32_t>(x) << RGB_565_SHIFT));
1178 #endif
1179 }
1180 
GetPixel32(int32_t x,int32_t y)1181 const uint32_t *PixelMap::GetPixel32(int32_t x, int32_t y)
1182 {
1183     if (!CheckValidParam(x, y) || (pixelBytes_ != ARGB_8888_BYTES)) {
1184         IMAGE_LOGE("get addr32 pixel position:(%{public}d, %{public}d) pixel bytes:%{public}d invalid.", x, y,
1185             pixelBytes_);
1186         return nullptr;
1187     }
1188     // convert uint8_t* to uint32_t*
1189 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1190     return reinterpret_cast<uint32_t *>(data_ + y * rowStride_ + (static_cast<uint32_t>(x) << ARGB_8888_SHIFT));
1191 #else
1192     return reinterpret_cast<uint32_t *>(data_ + y * rowDataSize_ + (static_cast<uint32_t>(x) << ARGB_8888_SHIFT));
1193 #endif
1194 }
1195 
GetPixel(int32_t x,int32_t y)1196 const uint8_t *PixelMap::GetPixel(int32_t x, int32_t y)
1197 {
1198     if (!CheckValidParam(x, y)) {
1199         IMAGE_LOGE("input pixel position:(%{public}d, %{public}d) invalid.", x, y);
1200         return nullptr;
1201     }
1202 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1203     return (data_ + y * rowStride_ + (static_cast<uint32_t>(x) * pixelBytes_));
1204 #else
1205     return (data_ + y * rowDataSize_ + (static_cast<uint32_t>(x) * pixelBytes_));
1206 #endif
1207 }
1208 
GetARGB32Color(int32_t x,int32_t y,uint32_t & color)1209 bool PixelMap::GetARGB32Color(int32_t x, int32_t y, uint32_t &color)
1210 {
1211     if (colorProc_ == nullptr) {
1212         IMAGE_LOGE("pixel format not supported.");
1213         return false;
1214     }
1215     const uint8_t *src = GetPixel(x, y);
1216     if (src == nullptr) {
1217         IMAGE_LOGE("get pixel color error.");
1218         return false;
1219     }
1220     // use founction point for frequently called interface
1221     return colorProc_(src, ONE_PIXEL_SIZE * pixelBytes_, &color, ONE_PIXEL_SIZE);
1222 }
1223 
ModifyImageProperty(const std::string & key,const std::string & value)1224 uint32_t PixelMap::ModifyImageProperty(const std::string &key, const std::string &value)
1225 {
1226     if (exifMetadata_ == nullptr) {
1227         return ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
1228     }
1229 
1230     if (!exifMetadata_->SetValue(key, value)) {
1231         return ERR_MEDIA_VALUE_INVALID;
1232     }
1233 
1234     return SUCCESS;
1235 }
1236 
GetImagePropertyInt(const std::string & key,int32_t & value)1237 uint32_t PixelMap::GetImagePropertyInt(const std::string &key, int32_t &value)
1238 {
1239     if (exifMetadata_ == nullptr) {
1240         return ERR_MEDIA_NO_EXIF_DATA;
1241     }
1242 
1243     std::string strValue;
1244     int  ret = exifMetadata_->GetValue(key, strValue);
1245     if (ret != SUCCESS) {
1246         return ret;
1247     }
1248 
1249     std::from_chars_result res = std::from_chars(strValue.data(), strValue.data() + strValue.size(), value);
1250     if (res.ec != std::errc()) {
1251         return ERR_IMAGE_SOURCE_DATA;
1252     }
1253 
1254     return SUCCESS;
1255 }
1256 
GetImagePropertyString(const std::string & key,std::string & value)1257 uint32_t PixelMap::GetImagePropertyString(const std::string &key, std::string &value)
1258 {
1259     if (exifMetadata_ == nullptr) {
1260         return ERR_MEDIA_NO_EXIF_DATA;
1261     }
1262 
1263     return exifMetadata_->GetValue(key, value);
1264 }
1265 
ALPHA8ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)1266 bool PixelMap::ALPHA8ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
1267 {
1268     if (in == nullptr || out == nullptr) {
1269         IMAGE_LOGE("ALPHA8ToARGB invalid input parameter: in or out is null");
1270         return false;
1271     }
1272     if (inCount != outCount) {
1273         IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1274         return false;
1275     }
1276     const uint8_t *src = in;
1277     for (uint32_t i = 0; i < outCount; i++) {
1278         *out++ = GetColorARGB(*src++, BYTE_ZERO, BYTE_ZERO, BYTE_ZERO);
1279     }
1280     return true;
1281 }
1282 
RGB565ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)1283 bool PixelMap::RGB565ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
1284 {
1285     if (in == nullptr || out == nullptr) {
1286         IMAGE_LOGE("RGB565ToARGB invalid input parameter: in or out is null");
1287         return false;
1288     }
1289     if (((inCount / RGB_565_BYTES) != outCount) && ((inCount % RGB_565_BYTES) != 0)) {
1290         IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1291         return false;
1292     }
1293     const uint16_t *src = reinterpret_cast<const uint16_t *>(in);
1294     for (uint32_t i = 0; i < outCount; i++) {
1295         uint16_t color = *src++;
1296         *out++ = GetColorARGB(BYTE_FULL, RGB565ToR32(color), RGB565ToG32(color), RGB565ToB32(color));
1297     }
1298     return true;
1299 }
1300 
ARGB8888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)1301 bool PixelMap::ARGB8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
1302 {
1303     if (in == nullptr || out == nullptr) {
1304         IMAGE_LOGE("ARGB8888ToARGB invalid input parameter: in or out is null");
1305         return false;
1306     }
1307     if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {
1308         IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1309         return false;
1310     }
1311     const uint32_t *src = reinterpret_cast<const uint32_t *>(in);
1312     for (uint32_t i = 0; i < outCount; i++) {
1313         uint32_t color = *src++;
1314         *out++ = GetColorARGB(GetColorComp(color, ARGB32_A_SHIFT), GetColorComp(color, ARGB32_R_SHIFT),
1315                               GetColorComp(color, ARGB32_G_SHIFT), GetColorComp(color, ARGB32_B_SHIFT));
1316     }
1317     return true;
1318 }
1319 
RGBA8888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)1320 bool PixelMap::RGBA8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
1321 {
1322     if (in == nullptr || out == nullptr) {
1323         IMAGE_LOGE("RGBA8888ToARGB invalid input parameter: in or out is null");
1324         return false;
1325     }
1326     if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {
1327         IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1328         return false;
1329     }
1330     const uint32_t *src = reinterpret_cast<const uint32_t *>(in);
1331     for (uint32_t i = 0; i < outCount; i++) {
1332         uint32_t color = *src++;
1333         *out++ = GetColorARGB(GetColorComp(color, RGBA32_A_SHIFT), GetColorComp(color, RGBA32_R_SHIFT),
1334                               GetColorComp(color, RGBA32_G_SHIFT), GetColorComp(color, RGBA32_B_SHIFT));
1335     }
1336     return true;
1337 }
1338 
BGRA8888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)1339 bool PixelMap::BGRA8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
1340 {
1341     if (in == nullptr || out == nullptr) {
1342         IMAGE_LOGE("BGRA8888ToARGB invalid input parameter: in or out is null");
1343         return false;
1344     }
1345     if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {
1346         IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1347         return false;
1348     }
1349     const uint32_t *src = reinterpret_cast<const uint32_t *>(in);
1350     for (uint32_t i = 0; i < outCount; i++) {
1351         uint32_t color = *src++;
1352         *out++ = GetColorARGB(GetColorComp(color, BGRA32_A_SHIFT), GetColorComp(color, BGRA32_R_SHIFT),
1353                               GetColorComp(color, BGRA32_G_SHIFT), GetColorComp(color, BGRA32_B_SHIFT));
1354     }
1355     return true;
1356 }
1357 
RGB888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)1358 bool PixelMap::RGB888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
1359 {
1360     if (in == nullptr || out == nullptr) {
1361         IMAGE_LOGE("RGB888ToARGB invalid input parameter: in or out is null");
1362         return false;
1363     }
1364     if (((inCount / RGB_888_BYTES) != outCount) && ((inCount % RGB_888_BYTES) != 0)) {
1365         IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1366         return false;
1367     }
1368     const uint8_t *src = in;
1369     for (uint32_t i = 0; i < outCount; i++) {
1370         uint8_t colorR = *src++;
1371         uint8_t colorG = *src++;
1372         uint8_t colorB = *src++;
1373         *out++ = GetColorARGB(BYTE_FULL, colorR, colorG, colorB);
1374     }
1375     return true;
1376 }
1377 
GetPixelBytes()1378 int32_t PixelMap::GetPixelBytes()
1379 {
1380     return pixelBytes_;
1381 }
1382 
GetRowBytes()1383 int32_t PixelMap::GetRowBytes()
1384 {
1385     return rowDataSize_;
1386 }
1387 
GetByteCount()1388 int32_t PixelMap::GetByteCount()
1389 {
1390     IMAGE_LOGD("GetByteCount");
1391     if (IsYUV(imageInfo_.pixelFormat)) {
1392         return GetYUVByteCount(imageInfo_);
1393     } else {
1394         uint64_t byteCount = static_cast<uint64_t>(rowDataSize_) * static_cast<uint64_t>(imageInfo_.size.height);
1395         if (byteCount > INT_MAX) {
1396             IMAGE_LOGE("GetByteCount failed: byteCount overflowed");
1397             return 0;
1398         }
1399         return byteCount;
1400     }
1401 }
1402 
GetWidth()1403 int32_t PixelMap::GetWidth()
1404 {
1405     return imageInfo_.size.width;
1406 }
1407 
GetHeight()1408 int32_t PixelMap::GetHeight()
1409 {
1410     return imageInfo_.size.height;
1411 }
1412 
GetTransformData(TransformData & transformData)1413 void PixelMap::GetTransformData(TransformData &transformData)
1414 {
1415     transformData = transformData_;
1416 }
1417 
SetTransformData(TransformData transformData)1418 void PixelMap::SetTransformData(TransformData transformData)
1419 {
1420     transformData_ = transformData;
1421 }
1422 
GetBaseDensity()1423 int32_t PixelMap::GetBaseDensity()
1424 {
1425     return imageInfo_.baseDensity;
1426 }
1427 
GetImageInfo(ImageInfo & imageInfo)1428 void PixelMap::GetImageInfo(ImageInfo &imageInfo)
1429 {
1430     imageInfo = imageInfo_;
1431 }
1432 
GetPixelFormat()1433 PixelFormat PixelMap::GetPixelFormat()
1434 {
1435     return imageInfo_.pixelFormat;
1436 }
1437 
GetColorSpace()1438 ColorSpace PixelMap::GetColorSpace()
1439 {
1440     return imageInfo_.colorSpace;
1441 }
1442 
GetAlphaType()1443 AlphaType PixelMap::GetAlphaType()
1444 {
1445     return imageInfo_.alphaType;
1446 }
1447 
GetPixels()1448 const uint8_t *PixelMap::GetPixels()
1449 {
1450     return data_;
1451 }
1452 
IsHdr()1453 bool PixelMap::IsHdr()
1454 {
1455     if (imageInfo_.pixelFormat != PixelFormat::RGBA_1010102 && imageInfo_.pixelFormat != PixelFormat::YCRCB_P010 &&
1456         imageInfo_.pixelFormat != PixelFormat::YCBCR_P010) {
1457         return false;
1458     }
1459 #ifdef IMAGE_COLORSPACE_FLAG
1460     OHOS::ColorManager::ColorSpace colorSpace = InnerGetGrColorSpace();
1461     if (colorSpace.GetColorSpaceName() != ColorManager::BT2020_HLG &&
1462         colorSpace.GetColorSpaceName() != ColorManager::BT2020_PQ &&
1463         colorSpace.GetColorSpaceName() != ColorManager::BT2020_HLG_LIMIT &&
1464         colorSpace.GetColorSpaceName() != ColorManager::BT2020_PQ_LIMIT) {
1465         return false;
1466     }
1467 #endif
1468     return true;
1469 }
1470 
GetARGB32ColorA(uint32_t color)1471 uint8_t PixelMap::GetARGB32ColorA(uint32_t color)
1472 {
1473     return (color >> ARGB_A_SHIFT) & ARGB_MASK;
1474 }
1475 
GetARGB32ColorR(uint32_t color)1476 uint8_t PixelMap::GetARGB32ColorR(uint32_t color)
1477 {
1478     return (color >> ARGB_R_SHIFT) & ARGB_MASK;
1479 }
1480 
GetARGB32ColorG(uint32_t color)1481 uint8_t PixelMap::GetARGB32ColorG(uint32_t color)
1482 {
1483     return (color >> ARGB_G_SHIFT) & ARGB_MASK;
1484 }
1485 
GetARGB32ColorB(uint32_t color)1486 uint8_t PixelMap::GetARGB32ColorB(uint32_t color)
1487 {
1488     return (color >> ARGB_B_SHIFT) & ARGB_MASK;
1489 }
1490 
IsSameImage(const PixelMap & other)1491 bool PixelMap::IsSameImage(const PixelMap &other)
1492 {
1493     if (isUnMap_ || data_ == nullptr || other.data_ == nullptr) {
1494         IMAGE_LOGE("IsSameImage data_ is nullptr, isUnMap %{public}d.", isUnMap_);
1495         return false;
1496     }
1497     if (imageInfo_.size.width != other.imageInfo_.size.width ||
1498         imageInfo_.size.height != other.imageInfo_.size.height ||
1499         imageInfo_.pixelFormat != other.imageInfo_.pixelFormat || imageInfo_.alphaType != other.imageInfo_.alphaType) {
1500         IMAGE_LOGI("IsSameImage imageInfo is not same");
1501         return false;
1502     }
1503     if (ImageUtils::CheckMulOverflow(rowDataSize_, imageInfo_.size.height)) {
1504         IMAGE_LOGI("IsSameImage imageInfo is invalid");
1505         return false;
1506     }
1507     uint64_t size = static_cast<uint64_t>(rowDataSize_) * static_cast<uint64_t>(imageInfo_.size.height);
1508     if (memcmp(data_, other.data_, size) != 0) {
1509         IMAGE_LOGI("IsSameImage memcmp is not same");
1510         return false;
1511     }
1512     return true;
1513 }
1514 
1515 // LCOV_EXCL_START
ReadPixels(const uint64_t & bufferSize,uint8_t * dst)1516 uint32_t PixelMap::ReadPixels(const uint64_t &bufferSize, uint8_t *dst)
1517 {
1518     ImageTrace imageTrace("ReadPixels by bufferSize");
1519     if (dst == nullptr) {
1520         IMAGE_LOGE("read pixels by buffer input dst address is null.");
1521         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1522     }
1523     if (isUnMap_ || data_ == nullptr) {
1524         IMAGE_LOGE("read pixels by buffer current PixelMap data is null, isUnMap %{public}d.", isUnMap_);
1525         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1526     }
1527     if (bufferSize < static_cast<uint64_t>(pixelsSize_)) {
1528         IMAGE_LOGE("read pixels by buffer input dst buffer(%{public}llu) < current pixelmap size(%{public}u).",
1529             static_cast<unsigned long long>(bufferSize), pixelsSize_);
1530         return ERR_IMAGE_INVALID_PARAMETER;
1531     }
1532     if (IsYUV(imageInfo_.pixelFormat)) {
1533         uint64_t tmpSize = 0;
1534         int readSize = MAX_READ_COUNT;
1535         while (tmpSize < bufferSize) {
1536             if (tmpSize + MAX_READ_COUNT > bufferSize) {
1537                 readSize = (int)(bufferSize - tmpSize);
1538             }
1539             errno_t ret = memcpy_s(dst + tmpSize, readSize, data_ + tmpSize, readSize);
1540             if (ret != 0) {
1541                 IMAGE_LOGE("read pixels by buffer memcpy the pixelmap data to dst fail, error:%{public}d", ret);
1542                 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1543             }
1544             tmpSize += static_cast<uint64_t>(readSize);
1545         }
1546     } else {
1547         // Copy the actual pixel data without padding bytes
1548         for (int i = 0; i < imageInfo_.size.height; ++i) {
1549             errno_t ret = memcpy_s(dst, rowDataSize_, data_ + i * rowStride_, rowDataSize_);
1550             if (ret != 0) {
1551                 IMAGE_LOGE("read pixels by buffer memcpy the pixelmap data to dst fail, error:%{public}d", ret);
1552                 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1553             }
1554             dst += rowDataSize_; // Move the destination buffer pointer to the next row
1555         }
1556     }
1557     return SUCCESS;
1558 }
1559 // LCOV_EXCL_STOP
1560 
IsSupportConvertToARGB(PixelFormat pixelFormat)1561 static bool IsSupportConvertToARGB(PixelFormat pixelFormat)
1562 {
1563     return pixelFormat == PixelFormat::RGB_565 || pixelFormat == PixelFormat::RGBA_8888 ||
1564         pixelFormat == PixelFormat::BGRA_8888 || pixelFormat == PixelFormat::RGB_888 ||
1565         pixelFormat == PixelFormat::NV21 || pixelFormat == PixelFormat::NV12;
1566 }
1567 
ReadARGBPixels(const uint64_t & bufferSize,uint8_t * dst)1568 uint32_t PixelMap::ReadARGBPixels(const uint64_t &bufferSize, uint8_t *dst)
1569 {
1570     ImageTrace imageTrace("ReadARGBPixels by bufferSize");
1571     if (dst == nullptr) {
1572         IMAGE_LOGE("Read ARGB pixels: input dst address is null.");
1573         return ERR_IMAGE_INVALID_PARAMETER;
1574     }
1575     if (isUnMap_ || data_ == nullptr) {
1576         IMAGE_LOGE("Read ARGB pixels: current PixelMap data is null, isUnMap %{public}d.", isUnMap_);
1577         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1578     }
1579     if (!IsSupportConvertToARGB(imageInfo_.pixelFormat)) {
1580         IMAGE_LOGE("Read ARGB pixels: does not support PixelMap with pixel format %{public}d.", imageInfo_.pixelFormat);
1581         return ERR_IMAGE_COLOR_CONVERT;
1582     }
1583     uint64_t minBufferSize = static_cast<uint64_t>(ARGB_8888_BYTES) *
1584         static_cast<uint64_t>(imageInfo_.size.width) * static_cast<uint64_t>(imageInfo_.size.height);
1585     if (bufferSize < minBufferSize || bufferSize > PIXEL_MAP_MAX_RAM_SIZE) {
1586         IMAGE_LOGE(
1587             "Read ARGB pixels: input dst buffer (%{public}llu) < required buffer size (%{public}llu), or too large.",
1588             static_cast<unsigned long long>(bufferSize), static_cast<unsigned long long>(minBufferSize));
1589         return ERR_IMAGE_INVALID_PARAMETER;
1590     }
1591 
1592     ImageInfo dstImageInfo = MakeImageInfo(imageInfo_.size.width, imageInfo_.size.height, PixelFormat::ARGB_8888,
1593         AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1594     BufferInfo srcInfo = {data_, GetRowStride(), imageInfo_};
1595     BufferInfo dstInfo = {dst, 0, dstImageInfo};
1596     int32_t dstLength = PixelConvert::PixelsConvert(srcInfo, dstInfo, bufferSize, IsStrideAlignment());
1597     if (dstLength < 0) {
1598         IMAGE_LOGE("ReadARGBPixels pixel convert to ARGB failed.");
1599         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1600     }
1601 
1602     ImageUtils::DumpDataIfDumpEnabled(reinterpret_cast<const char*>(dst), bufferSize, "dat", uniqueId_);
1603 
1604     return SUCCESS;
1605 }
1606 
CheckPixelsInput(const uint8_t * dst,const uint64_t & bufferSize,const uint32_t & offset,const uint32_t & stride,const Rect & region)1607 bool PixelMap::CheckPixelsInput(const uint8_t *dst, const uint64_t &bufferSize, const uint32_t &offset,
1608                                 const uint32_t &stride, const Rect &region)
1609 {
1610     if (dst == nullptr) {
1611         IMAGE_LOGE("CheckPixelsInput input dst address is null.");
1612         return false;
1613     }
1614 
1615     if (bufferSize == 0) {
1616         IMAGE_LOGE("CheckPixelsInput input buffer size is 0.");
1617         return false;
1618     }
1619 
1620     if (region.left < 0 || region.top < 0 || stride > numeric_limits<int32_t>::max() ||
1621         static_cast<uint64_t>(offset) > bufferSize) {
1622         IMAGE_LOGE(
1623             "CheckPixelsInput left(%{public}d) or top(%{public}d) or stride(%{public}u) or offset(%{public}u) < 0.",
1624             region.left, region.top, stride, offset);
1625         return false;
1626     }
1627     if (region.width <= 0 || region.height <= 0 || region.width > MAX_DIMENSION || region.height > MAX_DIMENSION) {
1628         IMAGE_LOGE("CheckPixelsInput width(%{public}d) or height(%{public}d) is < 0.", region.width, region.height);
1629         return false;
1630     }
1631     if (region.left > GetWidth() - region.width) {
1632         IMAGE_LOGE("CheckPixelsInput left(%{public}d) + width(%{public}d) is > pixelmap width(%{public}d).",
1633             region.left, region.width, GetWidth());
1634         return false;
1635     }
1636     if (region.top > GetHeight() - region.height) {
1637         IMAGE_LOGE("CheckPixelsInput top(%{public}d) + height(%{public}d) is > pixelmap height(%{public}d).",
1638             region.top, region.height, GetHeight());
1639         return false;
1640     }
1641     uint32_t regionStride = static_cast<uint32_t>(region.width) * 4;  // bytes count, need multiply by 4
1642     if (stride < regionStride) {
1643         IMAGE_LOGE("CheckPixelsInput stride(%{public}d) < width*4 (%{public}d).", stride, regionStride);
1644         return false;
1645     }
1646 
1647     if (bufferSize < regionStride) {
1648         IMAGE_LOGE("CheckPixelsInput input buffer size is < width * 4.");
1649         return false;
1650     }
1651     uint64_t lastLinePos = offset + static_cast<uint64_t>(region.height - 1) * stride;  // "1" is except the last line.
1652     if (static_cast<uint64_t>(offset) > (bufferSize - regionStride) || lastLinePos > (bufferSize - regionStride)) {
1653         IMAGE_LOGE(
1654             "CheckPixelsInput fail, height(%{public}d), width(%{public}d), lastLine(%{public}llu), "
1655             "offset(%{public}u), bufferSize:%{public}llu.", region.height, region.width,
1656             static_cast<unsigned long long>(lastLinePos), offset, static_cast<unsigned long long>(bufferSize));
1657         return false;
1658     }
1659     return true;
1660 }
1661 
1662 // LCOV_EXCL_START
ReadPixels(const uint64_t & bufferSize,const uint32_t & offset,const uint32_t & stride,const Rect & region,uint8_t * dst)1663 uint32_t PixelMap::ReadPixels(const uint64_t &bufferSize, const uint32_t &offset, const uint32_t &stride,
1664                               const Rect &region, uint8_t *dst)
1665 {
1666     if (!CheckPixelsInput(dst, bufferSize, offset, stride, region)) {
1667         IMAGE_LOGE("read pixels by rect input parameter fail.");
1668         return ERR_IMAGE_INVALID_PARAMETER;
1669     }
1670     if (isUnMap_ || data_ == nullptr) {
1671         IMAGE_LOGE("read pixels by rect this pixel data is null, isUnMap %{public}d.", isUnMap_);
1672         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1673     }
1674     ImageInfo dstImageInfo =
1675         MakeImageInfo(region.width, region.height, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1676     Position srcPosition { region.left, region.top };
1677     if (!PixelConvertAdapter::ReadPixelsConvert(data_, srcPosition, rowStride_, imageInfo_, dst + offset, stride,
1678         dstImageInfo)) {
1679         IMAGE_LOGE("read pixels by rect call ReadPixelsConvert fail.");
1680         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1681     }
1682     return SUCCESS;
1683 }
1684 
ReadPixel(const Position & pos,uint32_t & dst)1685 uint32_t PixelMap::ReadPixel(const Position &pos, uint32_t &dst)
1686 {
1687     if (pos.x < 0 || pos.y < 0 || pos.x >= GetWidth() || pos.y >= GetHeight()) {
1688         IMAGE_LOGE("read pixel by pos input invalid exception. [x(%{public}d), y(%{public}d)]", pos.x, pos.y);
1689         return ERR_IMAGE_INVALID_PARAMETER;
1690     }
1691     if (isUnMap_ || data_ == nullptr) {
1692         IMAGE_LOGE("read pixel by pos source data is null, isUnMap %{public}d.", isUnMap_);
1693         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1694     }
1695     ImageInfo dstImageInfo =
1696         MakeImageInfo(PER_PIXEL_LEN, PER_PIXEL_LEN, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1697     uint32_t dstRowBytes = BGRA_BYTES;
1698     Position srcPosition { pos.x, pos.y };
1699     if (!PixelConvertAdapter::ReadPixelsConvert(data_, srcPosition, rowStride_, imageInfo_, &dst, dstRowBytes,
1700         dstImageInfo)) {
1701         IMAGE_LOGE("read pixel by pos call ReadPixelsConvert fail.");
1702         return ERR_IMAGE_READ_PIXELMAP_FAILED;
1703     }
1704     return SUCCESS;
1705 }
1706 // LCOV_EXCL_STOP
1707 
ResetConfig(const Size & size,const PixelFormat & format)1708 uint32_t PixelMap::ResetConfig(const Size &size, const PixelFormat &format)
1709 {
1710     if (size.width <= 0 || size.height <= 0) {
1711         IMAGE_LOGE("ResetConfig reset input width(%{public}d) or height(%{public}d) is < 0.", size.width,
1712             size.height);
1713         return ERR_IMAGE_INVALID_PARAMETER;
1714     }
1715     uint32_t bytesPerPixel = ImageUtils::GetPixelBytes(format);
1716     if (bytesPerPixel == 0) {
1717         IMAGE_LOGE("ResetConfig get bytes by per pixel fail.");
1718         return ERR_IMAGE_INVALID_PARAMETER;
1719     }
1720     if (ImageUtils::CheckMulOverflow(size.width, size.height, bytesPerPixel)) {
1721         IMAGE_LOGE("ResetConfig reset input width(%{public}d) or height(%{public}d) is invalid.", size.width,
1722                    size.height);
1723         return ERR_IMAGE_INVALID_PARAMETER;
1724     }
1725     uint64_t dstSize = static_cast<uint64_t>(size.width) * static_cast<uint64_t>(size.height) * bytesPerPixel;
1726     if (dstSize > static_cast<uint64_t>(pixelsSize_)) {
1727         IMAGE_LOGE("ResetConfig reset dstSize(%{public}llu) > current(%{public}u).",
1728             static_cast<unsigned long long>(dstSize), pixelsSize_);
1729         return ERR_IMAGE_INVALID_PARAMETER;
1730     }
1731     AlphaType dstAlphaType = ImageUtils::GetValidAlphaTypeByFormat(GetAlphaType(), format);
1732     if (dstAlphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
1733         IMAGE_LOGE("ResetConfig Failed to get validate alpha type.");
1734         return ERR_IMAGE_INVALID_PARAMETER;
1735     }
1736     ImageInfo dstInfo = MakeImageInfo(size.width, size.height, format, dstAlphaType);
1737     uint32_t ret = SetImageInfo(dstInfo, true);
1738     if (ret != SUCCESS) {
1739         IMAGE_LOGE("ResetConfig call SetImageInfo Failed. ret:%{public}u", ret);
1740         return ERR_IMAGE_CONFIG_FAILED;
1741     }
1742     return SUCCESS;
1743 }
1744 
SetAlphaType(const AlphaType & alphaType)1745 bool PixelMap::SetAlphaType(const AlphaType &alphaType)
1746 {
1747     AlphaType type = ImageUtils::GetValidAlphaTypeByFormat(alphaType, imageInfo_.pixelFormat);
1748     if (type == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
1749         IMAGE_LOGE("SetAlphaType Failed to get validate alpha type.");
1750         return false;
1751     }
1752     ImageInfo dstInfo = imageInfo_;
1753     dstInfo.alphaType = type;
1754     uint32_t ret = SetImageInfo(dstInfo, true);
1755     if (ret != SUCCESS) {
1756         IMAGE_LOGE("SetAlphaType call SetImageInfo Failed. ret:%{public}u", ret);
1757         return false;
1758     }
1759     return true;
1760 }
1761 
1762 // LCOV_EXCL_START
WritePixel(const Position & pos,const uint32_t & color)1763 uint32_t PixelMap::WritePixel(const Position &pos, const uint32_t &color)
1764 {
1765     if (pos.x < 0 || pos.y < 0 || pos.x >= GetWidth() || pos.y >= GetHeight()) {
1766         IMAGE_LOGE(
1767             "write pixel by pos but input position is invalid. [x(%{public}d), y(%{public}d)]"\
1768             "Width() %{public}d,  Height() %{public}d, ", pos.x, pos.y, GetWidth(), GetHeight());
1769         return ERR_IMAGE_INVALID_PARAMETER;
1770     }
1771     if (!IsEditable()) {
1772         IMAGE_LOGE("write pixel by pos pixelmap is not editable.");
1773         return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
1774     }
1775     if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1776         IMAGE_LOGE("write pixel by pos current pixelmap image info is invalid.");
1777         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1778     }
1779     if (isUnMap_ || data_ == nullptr) {
1780         IMAGE_LOGE("write pixel by pos but current pixelmap data is nullptr, isUnMap %{public}d.", isUnMap_);
1781         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1782     }
1783     ImageInfo srcImageInfo =
1784         MakeImageInfo(PER_PIXEL_LEN, PER_PIXEL_LEN, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1785     uint32_t srcRowBytes = BGRA_BYTES;
1786     Position dstPosition { pos.x, pos.y };  // source is per pixel.
1787     if (!PixelConvertAdapter::WritePixelsConvert(&color, srcRowBytes, srcImageInfo, data_, dstPosition, rowStride_,
1788         imageInfo_)) {
1789         IMAGE_LOGE("write pixel by pos call WritePixelsConvert fail.");
1790         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1791     }
1792     return SUCCESS;
1793 }
1794 
WritePixels(const uint8_t * source,const uint64_t & bufferSize,const uint32_t & offset,const uint32_t & stride,const Rect & region)1795 uint32_t PixelMap::WritePixels(const uint8_t *source, const uint64_t &bufferSize, const uint32_t &offset,
1796                                const uint32_t &stride, const Rect &region)
1797 {
1798     if (!CheckPixelsInput(source, bufferSize, offset, stride, region)) {
1799         IMAGE_LOGE("write pixel by rect input parameter fail.");
1800         return ERR_IMAGE_INVALID_PARAMETER;
1801     }
1802     if (!IsEditable()) {
1803         IMAGE_LOGE("write pixel by rect pixelmap data is not editable.");
1804         return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
1805     }
1806     if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1807         IMAGE_LOGE("write pixel by rect current pixelmap image info is invalid.");
1808         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1809     }
1810     if (isUnMap_ || data_ == nullptr) {
1811         IMAGE_LOGE("write pixel by rect current pixel map data is null, isUnMap %{public}d.", isUnMap_);
1812         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1813     }
1814     uint32_t bytesPerPixel = ImageUtils::GetPixelBytes(imageInfo_.pixelFormat);
1815     if (bytesPerPixel == 0) {
1816         IMAGE_LOGE("write pixel by rect get bytes by per pixel fail.");
1817         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1818     }
1819     Position dstPosition { region.left, region.top };
1820     ImageInfo srcInfo =
1821         MakeImageInfo(region.width, region.height, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1822     if (!PixelConvertAdapter::WritePixelsConvert(source + offset, stride, srcInfo, data_, dstPosition, rowStride_,
1823         imageInfo_)) {
1824         IMAGE_LOGE("write pixel by rect call WritePixelsConvert fail.");
1825         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1826     }
1827     return SUCCESS;
1828 }
1829 
WritePixels(const uint8_t * source,const uint64_t & bufferSize)1830 uint32_t PixelMap::WritePixels(const uint8_t *source, const uint64_t &bufferSize)
1831 {
1832     ImageTrace imageTrace("WritePixels");
1833     if (source == nullptr || bufferSize < static_cast<uint64_t>(pixelsSize_)) {
1834         IMAGE_LOGE("write pixels by buffer source is nullptr or size(%{public}llu) < pixelSize(%{public}u).",
1835             static_cast<unsigned long long>(bufferSize), pixelsSize_);
1836         return ERR_IMAGE_INVALID_PARAMETER;
1837     }
1838     if (!IsEditable()) {
1839         IMAGE_LOGE("write pixels by buffer pixelmap data is not editable.");
1840         return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
1841     }
1842     if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1843         IMAGE_LOGE("write pixels by buffer current pixelmap image info is invalid.");
1844         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1845     }
1846     if (isUnMap_ || data_ == nullptr) {
1847         IMAGE_LOGE("write pixels by buffer current pixelmap data is nullptr, isUnMap %{public}d.", isUnMap_);
1848         return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1849     }
1850 
1851     if (IsYUV(imageInfo_.pixelFormat)) {
1852         uint64_t tmpSize = 0;
1853         int readSize = MAX_READ_COUNT;
1854         while (tmpSize < bufferSize) {
1855             if (tmpSize + MAX_READ_COUNT > bufferSize) {
1856                 readSize = (int)(bufferSize - tmpSize);
1857             }
1858             errno_t ret = memcpy_s(data_ + tmpSize, readSize, source + tmpSize, readSize);
1859             if (ret != 0) {
1860                 IMAGE_LOGE("write pixels by buffer memcpy the pixelmap data to dst fail, error:%{public}d", ret);
1861                 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1862             }
1863             tmpSize += static_cast<uint64_t>(readSize);
1864         }
1865     } else {
1866         for (int i = 0; i < imageInfo_.size.height; ++i) {
1867             const uint8_t* sourceRow = source + i * rowDataSize_;
1868             errno_t ret = memcpy_s(data_ + i * rowStride_, rowDataSize_, sourceRow, rowDataSize_);
1869             if (ret != 0) {
1870                 IMAGE_LOGE("write pixels by buffer memcpy the pixelmap data to dst fail, error:%{public}d", ret);
1871                 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1872             }
1873         }
1874     }
1875     return SUCCESS;
1876 }
1877 
WritePixels(const uint32_t & color)1878 bool PixelMap::WritePixels(const uint32_t &color)
1879 {
1880     if (!IsEditable()) {
1881         IMAGE_LOGE("erase pixels by color pixelmap data is not editable.");
1882         return false;
1883     }
1884     if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1885         IMAGE_LOGE("erase pixels by color current pixelmap image info is invalid.");
1886         return false;
1887     }
1888     if (isUnMap_ || data_ == nullptr) {
1889         IMAGE_LOGE("erase pixels by color current pixel map data is null, %{public}d.", isUnMap_);
1890         return false;
1891     }
1892     ImageInfo srcInfo =
1893         MakeImageInfo(imageInfo_.size.width, imageInfo_.size.height, imageInfo_.pixelFormat, imageInfo_.alphaType);
1894     if (!PixelConvertAdapter::EraseBitmap(data_, rowStride_, srcInfo, color)) {
1895         IMAGE_LOGE("erase pixels by color call EraseBitmap fail.");
1896         return false;
1897     }
1898     return true;
1899 }
1900 // LCOV_EXCL_STOP
1901 
IsStrideAlignment()1902 bool PixelMap::IsStrideAlignment()
1903 {
1904     if (allocatorType_ == AllocatorType::DMA_ALLOC) {
1905         IMAGE_LOGD("IsStrideAlignment allocatorType_ is DMA_ALLOC");
1906         return true;
1907     }
1908     return false;
1909 }
1910 
GetAllocatorType()1911 AllocatorType PixelMap::GetAllocatorType()
1912 {
1913     return allocatorType_;
1914 }
1915 
GetFd() const1916 void *PixelMap::GetFd() const
1917 {
1918     return context_;
1919 }
1920 
ReleaseMemory(AllocatorType allocType,void * addr,void * context,uint32_t size)1921 void PixelMap::ReleaseMemory(AllocatorType allocType, void *addr, void *context, uint32_t size)
1922 {
1923 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
1924     if (allocType == AllocatorType::SHARE_MEM_ALLOC) {
1925         if (context != nullptr) {
1926             int *fd = static_cast<int *>(context);
1927             if (addr != nullptr) {
1928                 ::munmap(addr, size);
1929             }
1930             if (fd != nullptr) {
1931                 ::close(*fd);
1932             }
1933             context = nullptr;
1934             addr = nullptr;
1935         }
1936     } else if (allocType == AllocatorType::HEAP_ALLOC) {
1937         if (addr != nullptr) {
1938             free(addr);
1939             addr = nullptr;
1940         }
1941     } else if (allocType == AllocatorType::DMA_ALLOC) {
1942         if (context != nullptr) {
1943             ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer*>(context));
1944         }
1945         context = nullptr;
1946         addr = nullptr;
1947     }
1948 #else
1949     if (addr != nullptr) {
1950         free(addr);
1951         addr = nullptr;
1952     }
1953 #endif
1954 }
1955 
1956 // LCOV_EXCL_START
WriteAshmemDataToParcel(Parcel & parcel,size_t size) const1957 bool PixelMap::WriteAshmemDataToParcel(Parcel &parcel, size_t size) const
1958 {
1959 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
1960     const uint8_t *data = data_;
1961     uint32_t id = GetUniqueId();
1962     std::string name = "Parcel ImageData, uniqueId: " + std::to_string(getpid()) + '_' + std::to_string(id);
1963     int fd = AshmemCreate(name.c_str(), size);
1964     IMAGE_LOGI("AshmemCreate:[%{public}d].", fd);
1965     if (fd < 0) {
1966         return false;
1967     }
1968 
1969     int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
1970     IMAGE_LOGD("AshmemSetProt:[%{public}d].", result);
1971     if (result < 0) {
1972         ::close(fd);
1973         return false;
1974     }
1975     void *ptr = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1976     if (ptr == MAP_FAILED) {
1977         ::close(fd);
1978         IMAGE_LOGE("WriteAshmemData map failed, errno:%{public}d", errno);
1979         return false;
1980     }
1981     IMAGE_LOGD("mmap success");
1982 
1983     if (memcpy_s(ptr, size, data, size) != EOK) {
1984         ::munmap(ptr, size);
1985         ::close(fd);
1986         IMAGE_LOGE("WriteAshmemData memcpy_s error");
1987         return false;
1988     }
1989 
1990     if (!WriteFileDescriptor(parcel, fd)) {
1991         ::munmap(ptr, size);
1992         ::close(fd);
1993         IMAGE_LOGE("WriteAshmemData WriteFileDescriptor error");
1994         return false;
1995     }
1996     IMAGE_LOGD("WriteAshmemData WriteFileDescriptor success");
1997     ::munmap(ptr, size);
1998     ::close(fd);
1999     return true;
2000 #endif
2001     IMAGE_LOGE("WriteAshmemData not support crossplatform");
2002     return false;
2003 }
2004 // LCOV_EXCL_STOP
2005 
WriteImageData(Parcel & parcel,size_t size) const2006 bool PixelMap::WriteImageData(Parcel &parcel, size_t size) const
2007 {
2008     const uint8_t *data = data_;
2009     if (isUnMap_ || data == nullptr || size > MAX_IMAGEDATA_SIZE) {
2010         IMAGE_LOGE("WriteImageData failed, data is null or size bigger than 128M, isUnMap %{public}d.", isUnMap_);
2011         return false;
2012     }
2013 
2014     if (!parcel.WriteInt32(size)) {
2015         IMAGE_LOGE("WriteImageData size failed.");
2016         return false;
2017     }
2018     if (size <= MIN_IMAGEDATA_SIZE) {
2019         return parcel.WriteUnpadBuffer(data, size);
2020     }
2021     return WriteAshmemDataToParcel(parcel, size);
2022 }
2023 
2024 // LCOV_EXCL_START
ReadHeapDataFromParcel(Parcel & parcel,int32_t bufferSize)2025 uint8_t *PixelMap::ReadHeapDataFromParcel(Parcel &parcel, int32_t bufferSize)
2026 {
2027     uint8_t *base = nullptr;
2028     if (bufferSize <= 0) {
2029         IMAGE_LOGE("malloc parameter bufferSize:[%{public}d] error.", bufferSize);
2030         return nullptr;
2031     }
2032 
2033     const uint8_t *ptr = parcel.ReadUnpadBuffer(bufferSize);
2034     if (ptr == nullptr) {
2035         IMAGE_LOGE("read buffer from parcel failed, read buffer addr is null");
2036         return nullptr;
2037     }
2038 
2039     base = static_cast<uint8_t *>(malloc(bufferSize));
2040     if (base == nullptr) {
2041         IMAGE_LOGE("alloc output pixel memory size:[%{public}d] error.", bufferSize);
2042         return nullptr;
2043     }
2044     if (memcpy_s(base, bufferSize, ptr, bufferSize) != 0) {
2045         free(base);
2046         base = nullptr;
2047         IMAGE_LOGE("memcpy pixel data size:[%{public}d] error.", bufferSize);
2048         return nullptr;
2049     }
2050     return base;
2051 }
2052 
ReadAshmemDataFromParcel(Parcel & parcel,int32_t bufferSize)2053 uint8_t *PixelMap::ReadAshmemDataFromParcel(Parcel &parcel, int32_t bufferSize)
2054 {
2055     uint8_t *base = nullptr;
2056 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
2057     int fd = ReadFileDescriptor(parcel);
2058     if (!CheckAshmemSize(fd, bufferSize)) {
2059         IMAGE_LOGE("ReadAshmemDataFromParcel check ashmem size failed, fd:[%{public}d].", fd);
2060         return nullptr;
2061     }
2062     if (bufferSize <= 0 || bufferSize > PIXEL_MAP_MAX_RAM_SIZE) {
2063         IMAGE_LOGE("malloc parameter bufferSize:[%{public}d] error.", bufferSize);
2064         return nullptr;
2065     }
2066 
2067     void *ptr = ::mmap(nullptr, bufferSize, PROT_READ, MAP_SHARED, fd, 0);
2068     if (ptr == MAP_FAILED) {
2069         // do not close fd here. fd will be closed in FileDescriptor, ::close(fd)
2070         IMAGE_LOGE("ReadImageData map failed, errno:%{public}d", errno);
2071         return nullptr;
2072     }
2073 
2074     base = static_cast<uint8_t *>(malloc(bufferSize));
2075     if (base == nullptr) {
2076         ::munmap(ptr, bufferSize);
2077         IMAGE_LOGE("alloc output pixel memory size:[%{public}d] error.", bufferSize);
2078         return nullptr;
2079     }
2080     if (memcpy_s(base, bufferSize, ptr, bufferSize) != 0) {
2081         ::munmap(ptr, bufferSize);
2082         free(base);
2083         base = nullptr;
2084         IMAGE_LOGE("memcpy pixel data size:[%{public}d] error.", bufferSize);
2085         return nullptr;
2086     }
2087 
2088     ReleaseMemory(AllocatorType::SHARE_MEM_ALLOC, ptr, &fd, bufferSize);
2089 #endif
2090     return base;
2091 }
2092 // LCOV_EXCL_STOP
2093 
ReadImageData(Parcel & parcel,int32_t bufferSize)2094 uint8_t *PixelMap::ReadImageData(Parcel &parcel, int32_t bufferSize)
2095 {
2096 #if !defined(_WIN32) && !defined(_APPLE) &&!defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
2097     if (static_cast<unsigned int>(bufferSize) <= MIN_IMAGEDATA_SIZE) {
2098         return ReadHeapDataFromParcel(parcel, bufferSize);
2099     } else {
2100         return ReadAshmemDataFromParcel(parcel, bufferSize);
2101     }
2102 #else
2103     return ReadHeapDataFromParcel(parcel, bufferSize);
2104 #endif
2105 }
2106 
WriteFileDescriptor(Parcel & parcel,int fd)2107 bool PixelMap::WriteFileDescriptor(Parcel &parcel, int fd)
2108 {
2109 #if !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
2110     if (fd < 0) {
2111         return false;
2112     }
2113     int dupFd = dup(fd);
2114     if (dupFd < 0) {
2115         return false;
2116     }
2117     sptr<IPCFileDescriptor> descriptor = new IPCFileDescriptor(dupFd);
2118     return parcel.WriteObject<IPCFileDescriptor>(descriptor);
2119 #else
2120     return false;
2121 #endif
2122 }
2123 
ReadFileDescriptor(Parcel & parcel)2124 int PixelMap::ReadFileDescriptor(Parcel &parcel)
2125 {
2126 #if !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
2127     sptr<IPCFileDescriptor> descriptor = parcel.ReadObject<IPCFileDescriptor>();
2128     if (descriptor == nullptr) {
2129         return -1;
2130     }
2131     int fd = descriptor->GetFd();
2132     if (fd < 0) {
2133         return -1;
2134     }
2135     return dup(fd);
2136 #else
2137     return -1;
2138 #endif
2139 }
2140 
WriteImageInfo(Parcel & parcel) const2141 bool PixelMap::WriteImageInfo(Parcel &parcel) const
2142 {
2143     if (!parcel.WriteInt32(imageInfo_.size.width)) {
2144         IMAGE_LOGE("write image info width:[%{public}d] to parcel failed.", imageInfo_.size.width);
2145         return false;
2146     }
2147     if (!parcel.WriteInt32(imageInfo_.size.height)) {
2148         IMAGE_LOGE("write image info height:[%{public}d] to parcel failed.", imageInfo_.size.height);
2149         return false;
2150     }
2151     if (!parcel.WriteInt32(static_cast<int32_t>(imageInfo_.pixelFormat))) {
2152         IMAGE_LOGE("write image info pixel format:[%{public}d] to parcel failed.", imageInfo_.pixelFormat);
2153         return false;
2154     }
2155     if (!parcel.WriteInt32(static_cast<int32_t>(imageInfo_.colorSpace))) {
2156         IMAGE_LOGE("write image info color space:[%{public}d] to parcel failed.", imageInfo_.colorSpace);
2157         return false;
2158     }
2159     if (!parcel.WriteInt32(static_cast<int32_t>(imageInfo_.alphaType))) {
2160         IMAGE_LOGE("write image info alpha type:[%{public}d] to parcel failed.", imageInfo_.alphaType);
2161         return false;
2162     }
2163     if (!parcel.WriteInt32(imageInfo_.baseDensity)) {
2164         IMAGE_LOGE("write image info base density:[%{public}d] to parcel failed.", imageInfo_.baseDensity);
2165         return false;
2166     }
2167     if (!parcel.WriteString(imageInfo_.encodedFormat)) {
2168         IMAGE_LOGE("write image info encoded format:[%{public}s] to parcel failed.", imageInfo_.encodedFormat.c_str());
2169         return false;
2170     }
2171     return true;
2172 }
2173 
WritePropertiesToParcel(Parcel & parcel) const2174 bool PixelMap::WritePropertiesToParcel(Parcel &parcel) const
2175 {
2176     if (!WriteImageInfo(parcel)) {
2177         IMAGE_LOGE("write image info to parcel failed.");
2178         return false;
2179     }
2180 
2181     if (!parcel.WriteBool(editable_)) {
2182         IMAGE_LOGE("write pixel map editable to parcel failed.");
2183         return false;
2184     }
2185 
2186     if (!parcel.WriteBool(isAstc_)) {
2187         IMAGE_LOGE("write pixel map isAstc_ to parcel failed.");
2188         return false;
2189     }
2190 
2191     if (!parcel.WriteInt32(static_cast<int32_t>(allocatorType_))) {
2192         IMAGE_LOGE("write pixel map allocator type:[%{public}d] to parcel failed.", allocatorType_);
2193         return false;
2194     }
2195 
2196     if (!parcel.WriteInt32(static_cast<int32_t>(grColorSpace_ ?
2197             grColorSpace_->GetColorSpaceName() : ERR_MEDIA_INVALID_VALUE))) {
2198         IMAGE_LOGE("write pixel map grColorSpace to parcel failed.");
2199         return false;
2200     }
2201 
2202     if (!parcel.WriteInt32(static_cast<int32_t>(rowDataSize_))) {
2203         IMAGE_LOGE("write image info rowStride_:[%{public}d] to parcel failed.", rowDataSize_);
2204         return false;
2205     }
2206     return true;
2207 }
2208 
WriteMemInfoToParcel(Parcel & parcel,const int32_t & bufferSize) const2209 bool PixelMap::WriteMemInfoToParcel(Parcel &parcel, const int32_t &bufferSize) const
2210 {
2211 #if !defined(_WIN32) && !defined(_APPLE) &&!defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
2212     if (allocatorType_ == AllocatorType::SHARE_MEM_ALLOC) {
2213         if (!parcel.WriteInt32(bufferSize)) {
2214             return false;
2215         }
2216 
2217         int *fd = static_cast<int *>(context_);
2218         if (fd == nullptr || *fd <= 0) {
2219             IMAGE_LOGD("write pixel map failed, fd is [%{public}d] or fd <= 0.", fd == nullptr ? 1 : 0);
2220             return false;
2221         }
2222         if (!CheckAshmemSize(*fd, bufferSize, isAstc_)) {
2223             IMAGE_LOGE("write pixel map check ashmem size failed, fd:[%{public}d].", *fd);
2224             return false;
2225         }
2226         if (!WriteFileDescriptor(parcel, *fd)) {
2227             IMAGE_LOGE("write pixel map fd:[%{public}d] to parcel failed.", *fd);
2228             ::close(*fd);
2229             return false;
2230         }
2231     } else if (allocatorType_ == AllocatorType::DMA_ALLOC) {
2232         if (!parcel.WriteInt32(bufferSize)) {
2233             return false;
2234         }
2235         SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(context_);
2236         if (sbBuffer == nullptr) {
2237             IMAGE_LOGE("write pixel map failed, surface buffer is null");
2238             return false;
2239         }
2240         GSError ret = sbBuffer->WriteToMessageParcel(static_cast<MessageParcel&>(parcel));
2241         if (ret != GSError::GSERROR_OK) {
2242             IMAGE_LOGE("write pixel map to message parcel failed: %{public}s.", GSErrorStr(ret).c_str());
2243             return false;
2244         }
2245     } else {
2246         if (!WriteImageData(parcel, bufferSize)) {
2247             IMAGE_LOGE("write pixel map buffer to parcel failed.");
2248             return false;
2249         }
2250     }
2251 #else
2252     if (!WriteImageData(parcel, bufferSize)) {
2253         IMAGE_LOGE("write pixel map buffer to parcel failed.");
2254         return false;
2255     }
2256 #endif
2257     return true;
2258 }
2259 
WriteTransformDataToParcel(Parcel & parcel) const2260 bool PixelMap::WriteTransformDataToParcel(Parcel &parcel) const
2261 {
2262     if (isAstc_) {
2263         if (!parcel.WriteFloat(static_cast<float>(transformData_.scaleX))) {
2264             IMAGE_LOGE("write scaleX:[%{public}f] to parcel failed.", transformData_.scaleX);
2265             return false;
2266         }
2267         if (!parcel.WriteFloat(static_cast<float>(transformData_.scaleY))) {
2268             IMAGE_LOGE("write scaleY:[%{public}f] to parcel failed.", transformData_.scaleY);
2269             return false;
2270         }
2271         if (!parcel.WriteFloat(static_cast<float>(transformData_.rotateD))) {
2272             IMAGE_LOGE("write rotateD:[%{public}f] to parcel failed.", transformData_.rotateD);
2273             return false;
2274         }
2275         if (!parcel.WriteFloat(static_cast<float>(transformData_.cropLeft))) {
2276             IMAGE_LOGE("write cropLeft:[%{public}f] to parcel failed.", transformData_.cropLeft);
2277             return false;
2278         }
2279         if (!parcel.WriteFloat(static_cast<float>(transformData_.cropTop))) {
2280             IMAGE_LOGE("write cropTop:[%{public}f] to parcel failed.", transformData_.cropTop);
2281             return false;
2282         }
2283         if (!parcel.WriteFloat(static_cast<float>(transformData_.cropWidth))) {
2284             IMAGE_LOGE("write cropWidth:[%{public}f] to parcel failed.", transformData_.cropWidth);
2285             return false;
2286         }
2287         if (!parcel.WriteFloat(static_cast<float>(transformData_.cropHeight))) {
2288             IMAGE_LOGE("write cropHeight:[%{public}f] to parcel failed.", transformData_.cropHeight);
2289             return false;
2290         }
2291         if (!parcel.WriteFloat(static_cast<float>(transformData_.translateX))) {
2292             IMAGE_LOGE("write translateX:[%{public}f] to parcel failed.", transformData_.translateX);
2293             return false;
2294         }
2295         if (!parcel.WriteFloat(static_cast<float>(transformData_.translateY))) {
2296             IMAGE_LOGE("write translateY:[%{public}f] to parcel failed.", transformData_.translateY);
2297             return false;
2298         }
2299         if (!parcel.WriteBool(static_cast<bool>(transformData_.flipX))) {
2300             IMAGE_LOGE("write astc transformData_.flipX to parcel failed.");
2301             return false;
2302         }
2303         if (!parcel.WriteBool(static_cast<bool>(transformData_.flipY))) {
2304             IMAGE_LOGE("write astc transformData_.flipY to parcel failed.");
2305             return false;
2306         }
2307     }
2308     return true;
2309 }
2310 
WriteYuvDataInfoToParcel(Parcel & parcel) const2311 bool PixelMap::WriteYuvDataInfoToParcel(Parcel &parcel) const
2312 {
2313     if (IsYuvFormat()) {
2314         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.imageSize.width))) {
2315             return false;
2316         }
2317         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.imageSize.height))) {
2318             return false;
2319         }
2320         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.yWidth))) {
2321             return false;
2322         }
2323         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.yHeight))) {
2324             return false;
2325         }
2326         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.uvWidth))) {
2327             return false;
2328         }
2329         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.uvHeight))) {
2330             return false;
2331         }
2332         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.yStride))) {
2333             return false;
2334         }
2335         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.uStride))) {
2336             return false;
2337         }
2338         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.vStride))) {
2339             return false;
2340         }
2341         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.uvStride))) {
2342             return false;
2343         }
2344         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.yOffset))) {
2345             return false;
2346         }
2347         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.uOffset))) {
2348             return false;
2349         }
2350         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.vOffset))) {
2351             return false;
2352         }
2353         if (!parcel.WriteInt32(static_cast<int32_t>(yuvDataInfo_.uvOffset))) {
2354             return false;
2355         }
2356     }
2357     return true;
2358 }
2359 
WriteAstcRealSizeToParcel(Parcel & parcel) const2360 bool PixelMap::WriteAstcRealSizeToParcel(Parcel &parcel) const
2361 {
2362     if (isAstc_) {
2363         if (!parcel.WriteInt32(static_cast<int32_t>(astcrealSize_.width))) {
2364             IMAGE_LOGE("write astcrealSize_.width:[%{public}d] to parcel failed.", astcrealSize_.width);
2365             return false;
2366         }
2367         if (!parcel.WriteInt32(static_cast<int32_t>(astcrealSize_.height))) {
2368             IMAGE_LOGE("write astcrealSize_.height:[%{public}d] to parcel failed.", astcrealSize_.height);
2369             return false;
2370         }
2371     }
2372     return true;
2373 }
2374 
Marshalling(Parcel & parcel) const2375 bool PixelMap::Marshalling(Parcel &parcel) const
2376 {
2377     int32_t PIXEL_MAP_INFO_MAX_LENGTH = 128;
2378     if (ImageUtils::CheckMulOverflow(imageInfo_.size.height, rowDataSize_)) {
2379         IMAGE_LOGE("pixelmap invalid params, height:%{public}d, rowDataSize:%{public}d.",
2380                    imageInfo_.size.height, rowDataSize_);
2381         return false;
2382     }
2383     int32_t bufferSize = rowDataSize_ * imageInfo_.size.height;
2384     if (isAstc_ || IsYUV(imageInfo_.pixelFormat) || imageInfo_.pixelFormat == PixelFormat::RGBA_F16) {
2385         bufferSize = pixelsSize_;
2386     }
2387     if (static_cast<size_t>(bufferSize) <= MIN_IMAGEDATA_SIZE &&
2388         static_cast<size_t>(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH) > parcel.GetDataCapacity() &&
2389         !parcel.SetDataCapacity(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH)) {
2390         IMAGE_LOGE("set parcel max capacity:[%{public}d] failed.", bufferSize + PIXEL_MAP_INFO_MAX_LENGTH);
2391         return false;
2392     }
2393     if (!WritePropertiesToParcel(parcel)) {
2394         IMAGE_LOGE("write info to parcel failed.");
2395         return false;
2396     }
2397     if (!WriteMemInfoToParcel(parcel, bufferSize)) {
2398         IMAGE_LOGD("write memory info to parcel failed.");
2399         return false;
2400     }
2401 
2402     if (!WriteTransformDataToParcel(parcel)) {
2403         IMAGE_LOGE("write transformData to parcel failed.");
2404         return false;
2405     }
2406     if (!WriteAstcRealSizeToParcel(parcel)) {
2407         IMAGE_LOGE("write astcrealSize to parcel failed.");
2408         return false;
2409     }
2410 
2411     if (!WriteYuvDataInfoToParcel(parcel)) {
2412         IMAGE_LOGE("write WriteYuvDataInfoToParcel to parcel failed.");
2413         return false;
2414     }
2415     return true;
2416 }
2417 
ReadImageInfo(Parcel & parcel,ImageInfo & imgInfo)2418 bool PixelMap::ReadImageInfo(Parcel &parcel, ImageInfo &imgInfo)
2419 {
2420     imgInfo.size.width = parcel.ReadInt32();
2421     IMAGE_LOGD("read pixel map width:[%{public}d] to parcel.", imgInfo.size.width);
2422     imgInfo.size.height = parcel.ReadInt32();
2423     IMAGE_LOGD("read pixel map height:[%{public}d] to parcel.", imgInfo.size.height);
2424     if (imgInfo.size.width <= 0 || imgInfo.size.height <= 0) {
2425         IMAGE_LOGE("invalid width:[%{public}d] or height:[%{public}d]", imgInfo.size.width, imgInfo.size.height);
2426         return false;
2427     }
2428     imgInfo.pixelFormat = static_cast<PixelFormat>(parcel.ReadInt32());
2429     IMAGE_LOGD("read pixel map pixelFormat:[%{public}d] to parcel.", imgInfo.pixelFormat);
2430     imgInfo.colorSpace = static_cast<ColorSpace>(parcel.ReadInt32());
2431     IMAGE_LOGD("read pixel map colorSpace:[%{public}d] to parcel.", imgInfo.colorSpace);
2432     imgInfo.alphaType = static_cast<AlphaType>(parcel.ReadInt32());
2433     IMAGE_LOGD("read pixel map alphaType:[%{public}d] to parcel.", imgInfo.alphaType);
2434     imgInfo.baseDensity = parcel.ReadInt32();
2435     imgInfo.encodedFormat = parcel.ReadString();
2436     return true;
2437 }
2438 
ReadTransformData(Parcel & parcel,PixelMap * pixelMap)2439 bool PixelMap::ReadTransformData(Parcel &parcel, PixelMap *pixelMap)
2440 {
2441     if (pixelMap == nullptr) {
2442         IMAGE_LOGE("ReadTransformData invalid input parameter: pixelMap is null");
2443         return false;
2444     }
2445 
2446     if (pixelMap->IsAstc()) {
2447         TransformData transformData;
2448         transformData.scaleX = parcel.ReadFloat();
2449         transformData.scaleY = parcel.ReadFloat();
2450         transformData.rotateD = parcel.ReadFloat();
2451         transformData.cropLeft = parcel.ReadFloat();
2452         transformData.cropTop = parcel.ReadFloat();
2453         transformData.cropWidth = parcel.ReadFloat();
2454         transformData.cropHeight = parcel.ReadFloat();
2455         transformData.translateX = parcel.ReadFloat();
2456         transformData.translateY = parcel.ReadFloat();
2457         transformData.flipX = parcel.ReadBool();
2458         transformData.flipY = parcel.ReadBool();
2459         pixelMap->SetTransformData(transformData);
2460     }
2461     return true;
2462 }
2463 
ReadYuvDataInfoFromParcel(Parcel & parcel,PixelMap * pixelMap)2464 bool PixelMap::ReadYuvDataInfoFromParcel(Parcel &parcel, PixelMap *pixelMap)
2465 {
2466     if (IsYuvFormat()) {
2467         YUVDataInfo yDataInfo;
2468         yDataInfo.imageSize.width = parcel.ReadInt32();
2469         IMAGE_LOGD("ReadYuvDataInfoFromParcel width:%{public}d", yDataInfo.imageSize.width);
2470         yDataInfo.imageSize.height = parcel.ReadInt32();
2471         IMAGE_LOGD("ReadYuvDataInfoFromParcel height:%{public}d", yDataInfo.imageSize.height);
2472 
2473         yDataInfo.yWidth = parcel.ReadUint32();
2474         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.yWidth:%{public}d", yDataInfo.yWidth);
2475         yDataInfo.yHeight = parcel.ReadUint32();
2476         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.yHeight:%{public}d", yDataInfo.yHeight);
2477         yDataInfo.uvWidth = parcel.ReadUint32();
2478         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.uvWidth:%{public}d", yDataInfo.uvWidth);
2479         yDataInfo.uvHeight = parcel.ReadUint32();
2480         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.uvHeight:%{public}d", yDataInfo.uvHeight);
2481 
2482         yDataInfo.yStride = parcel.ReadUint32();
2483         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.yStride:%{public}d", yDataInfo.yStride);
2484         yDataInfo.uStride = parcel.ReadUint32();
2485         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.uStride:%{public}d", yDataInfo.uStride);
2486         yDataInfo.vStride = parcel.ReadUint32();
2487         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.vStride:%{public}d", yDataInfo.vStride);
2488         yDataInfo.uvStride = parcel.ReadUint32();
2489         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.uvStride:%{public}d", yDataInfo.uvStride);
2490 
2491         yDataInfo.yOffset = parcel.ReadUint32();
2492         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.yOffset:%{public}d", yDataInfo.yOffset);
2493         yDataInfo.uOffset = parcel.ReadUint32();
2494         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.uOffset:%{public}d", yDataInfo.uOffset);
2495         yDataInfo.vOffset = parcel.ReadUint32();
2496         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.vOffset:%{public}d", yDataInfo.vOffset);
2497         yDataInfo.uvOffset = parcel.ReadUint32();
2498         IMAGE_LOGD("ReadYuvDataInfoFromParcel yDataInfo.uvOffset:%{public}d", yDataInfo.uvOffset);
2499 
2500         SetImageYUVInfo(yDataInfo);
2501     }
2502     return true;
2503 }
2504 
ReadAstcRealSize(Parcel & parcel,PixelMap * pixelMap)2505 bool PixelMap::ReadAstcRealSize(Parcel &parcel, PixelMap *pixelMap)
2506 {
2507     if (pixelMap == nullptr) {
2508         IMAGE_LOGE("ReadAstcRealSize invalid input parameter: pixelMap is null");
2509         return false;
2510     }
2511 
2512     if (pixelMap->IsAstc()) {
2513         Size realSize;
2514         realSize.width = parcel.ReadInt32();
2515         realSize.height = parcel.ReadInt32();
2516         pixelMap->SetAstcRealSize(realSize);
2517     }
2518     return true;
2519 }
2520 
ReadPropertiesFromParcel(Parcel & parcel,ImageInfo & imgInfo,AllocatorType & allocatorType,int32_t & bufferSize,PIXEL_MAP_ERR & error)2521 bool PixelMap::ReadPropertiesFromParcel(Parcel &parcel, ImageInfo &imgInfo,
2522     AllocatorType &allocatorType, int32_t &bufferSize, PIXEL_MAP_ERR &error)
2523 {
2524     bool isEditable = parcel.ReadBool();
2525     SetEditable(isEditable);
2526     bool isAstc = parcel.ReadBool();
2527     SetAstc(isAstc);
2528 
2529     allocatorType = static_cast<AllocatorType>(parcel.ReadInt32());
2530     if (allocatorType == AllocatorType::DEFAULT || allocatorType == AllocatorType::CUSTOM_ALLOC) {
2531         allocatorType = AllocatorType::HEAP_ALLOC;
2532     }
2533 
2534     int32_t csm = parcel.ReadInt32();
2535     if (csm != ERR_MEDIA_INVALID_VALUE) {
2536         OHOS::ColorManager::ColorSpaceName colorSpaceName = static_cast<OHOS::ColorManager::ColorSpaceName>(csm);
2537         OHOS::ColorManager::ColorSpace grColorSpace = OHOS::ColorManager::ColorSpace(colorSpaceName);
2538         InnerSetColorSpace(grColorSpace);
2539     }
2540 
2541     int32_t rowDataSize = parcel.ReadInt32();
2542     bufferSize = parcel.ReadInt32();
2543     int32_t bytesPerPixel = ImageUtils::GetPixelBytes(imgInfo.pixelFormat);
2544     if (bytesPerPixel == 0 ||
2545         rowDataSize != ImageUtils::GetRowDataSizeByPixelFormat(imgInfo.size.width, imgInfo.pixelFormat)) {
2546         IMAGE_LOGE("ReadPropertiesFromParcel bytesPerPixel or rowDataSize (%{public}d) invalid", rowDataSize);
2547         PixelMap::ConstructPixelMapError(error, ERR_IMAGE_PIXELMAP_CREATE_FAILED,
2548             "bytesPerPixel or rowDataSize invalid");
2549         return false;
2550     }
2551 
2552     uint64_t expectedBufferSize = static_cast<uint64_t>(rowDataSize) * static_cast<uint64_t>(imgInfo.size.height);
2553     if (!isAstc && !IsYUV(imgInfo.pixelFormat) && imgInfo.pixelFormat != PixelFormat::RGBA_F16 &&
2554         (expectedBufferSize > (allocatorType == AllocatorType::HEAP_ALLOC ? PIXEL_MAP_MAX_RAM_SIZE : INT_MAX) ||
2555         static_cast<uint64_t>(bufferSize) != expectedBufferSize)) {
2556         IMAGE_LOGE("ReadPropertiesFromParcel bufferSize invalid, expect: %{public}llu, actual: %{public}d",
2557             static_cast<unsigned long long>(expectedBufferSize), bufferSize);
2558         PixelMap::ConstructPixelMapError(error, ERR_IMAGE_PIXELMAP_CREATE_FAILED, "bufferSize invalid");
2559         return false;
2560     }
2561     return true;
2562 }
2563 
2564 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
ReadDmaMemInfoFromParcel(Parcel & parcel,PixelMemInfo & pixelMemInfo)2565 bool ReadDmaMemInfoFromParcel(Parcel &parcel, PixelMemInfo &pixelMemInfo)
2566 {
2567     sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
2568     if (surfaceBuffer == nullptr) {
2569         IMAGE_LOGE("SurfaceBuffer failed to be created");
2570         return false;
2571     }
2572     GSError ret = surfaceBuffer->ReadFromMessageParcel(static_cast<MessageParcel&>(parcel));
2573     if (ret != GSError::GSERROR_OK) {
2574         IMAGE_LOGE("SurfaceBuffer read from message parcel failed: %{public}s", GSErrorStr(ret).c_str());
2575         return false;
2576     }
2577 
2578     void* nativeBuffer = surfaceBuffer.GetRefPtr();
2579     ImageUtils::SurfaceBuffer_Reference(nativeBuffer);
2580     pixelMemInfo.base = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
2581     pixelMemInfo.context = nativeBuffer;
2582     return true;
2583 }
2584 #endif
2585 
ReadMemInfoFromParcel(Parcel & parcel,PixelMemInfo & pixelMemInfo,PIXEL_MAP_ERR & error)2586 bool PixelMap::ReadMemInfoFromParcel(Parcel &parcel, PixelMemInfo &pixelMemInfo, PIXEL_MAP_ERR &error)
2587 {
2588 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
2589     if (pixelMemInfo.allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
2590         int fd = ReadFileDescriptor(parcel);
2591         if (!CheckAshmemSize(fd, pixelMemInfo.bufferSize, pixelMemInfo.isAstc)) {
2592             PixelMap::ConstructPixelMapError(error, ERR_IMAGE_GET_FD_BAD, "fd acquisition failed");
2593             ::close(fd);
2594             return false;
2595         }
2596         void* ptr = ::mmap(nullptr, pixelMemInfo.bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
2597         if (ptr == MAP_FAILED) {
2598             ptr = ::mmap(nullptr, pixelMemInfo.bufferSize, PROT_READ, MAP_SHARED, fd, 0);
2599             if (ptr == MAP_FAILED) {
2600                 ::close(fd);
2601                 IMAGE_LOGE("shared memory map in memalloc failed, errno:%{public}d", errno);
2602                 PixelMap::ConstructPixelMapError(error, ERR_IMAGE_GET_FD_BAD, "shared memory map in memalloc failed");
2603                 return false;
2604             }
2605         }
2606         pixelMemInfo.context = new(std::nothrow) int32_t();
2607         if (pixelMemInfo.context == nullptr) {
2608             ::munmap(ptr, pixelMemInfo.bufferSize);
2609             ::close(fd);
2610             return false;
2611         }
2612         *static_cast<int32_t *>(pixelMemInfo.context) = fd;
2613         pixelMemInfo.base = static_cast<uint8_t *>(ptr);
2614     } else if (pixelMemInfo.allocatorType == AllocatorType::DMA_ALLOC) {
2615         if (!ReadDmaMemInfoFromParcel(parcel, pixelMemInfo)) {
2616             PixelMap::ConstructPixelMapError(error, ERR_IMAGE_GET_DATA_ABNORMAL, "ReadFromMessageParcel failed");
2617             return false;
2618         }
2619     } else { // Any other allocator types will malloc HEAP memory
2620         pixelMemInfo.base = ReadImageData(parcel, pixelMemInfo.bufferSize);
2621         if (pixelMemInfo.base == nullptr) {
2622             PixelMap::ConstructPixelMapError(error, ERR_IMAGE_GET_DATA_ABNORMAL, "ReadImageData failed");
2623             return false;
2624         }
2625     }
2626 #else
2627     pixelMemInfo.base = ReadImageData(parcel, pixelMemInfo.bufferSize);
2628     if (pixelMemInfo.base == nullptr) {
2629         IMAGE_LOGE("get pixel memory size:[%{public}d] error.", pixelMemInfo.bufferSize);
2630         return false;
2631     }
2632 #endif
2633     return true;
2634 }
2635 
UpdatePixelMapMemInfo(PixelMap * pixelMap,ImageInfo & imgInfo,PixelMemInfo & pixelMemInfo)2636 bool PixelMap::UpdatePixelMapMemInfo(PixelMap *pixelMap, ImageInfo &imgInfo, PixelMemInfo &pixelMemInfo)
2637 {
2638     if (pixelMap == nullptr) {
2639         IMAGE_LOGE("UpdatePixelMapMemInfo invalid input parameter: pixelMap is null");
2640         return false;
2641     }
2642 
2643     uint32_t ret = pixelMap->SetImageInfo(imgInfo);
2644     if (ret != SUCCESS) {
2645         if (pixelMap->freePixelMapProc_ != nullptr) {
2646             pixelMap->freePixelMapProc_(pixelMemInfo.base, pixelMemInfo.context, pixelMemInfo.bufferSize);
2647         }
2648         ReleaseMemory(pixelMemInfo.allocatorType, pixelMemInfo.base, pixelMemInfo.context, pixelMemInfo.bufferSize);
2649         if (pixelMemInfo.allocatorType == AllocatorType::SHARE_MEM_ALLOC && pixelMemInfo.context != nullptr) {
2650             delete static_cast<int32_t *>(pixelMemInfo.context);
2651             pixelMemInfo.context = nullptr;
2652         }
2653         IMAGE_LOGE("create pixel map from parcel failed, set image info error.");
2654         return false;
2655     }
2656     pixelMap->SetPixelsAddr(pixelMemInfo.base, pixelMemInfo.context,
2657         pixelMemInfo.bufferSize, pixelMemInfo.allocatorType, nullptr);
2658     return true;
2659 }
2660 
Unmarshalling(Parcel & parcel)2661 PixelMap *PixelMap::Unmarshalling(Parcel &parcel)
2662 {
2663     PIXEL_MAP_ERR error;
2664     PixelMap* dstPixelMap = PixelMap::Unmarshalling(parcel, error);
2665     if (dstPixelMap == nullptr || error.errorCode != SUCCESS) {
2666         IMAGE_LOGE("unmarshalling failed errorCode:%{public}d, errorInfo:%{public}s",
2667             error.errorCode, error.errorInfo.c_str());
2668     }
2669     return dstPixelMap;
2670 }
2671 
Unmarshalling(Parcel & parcel,PIXEL_MAP_ERR & error)2672 PixelMap *PixelMap::Unmarshalling(Parcel &parcel, PIXEL_MAP_ERR &error)
2673 {
2674     ImageInfo imgInfo;
2675     PixelMap *pixelMap = nullptr;
2676     if (!ReadImageInfo(parcel, imgInfo)) {
2677         IMAGE_LOGE("read imageInfo fail");
2678         PixelMap::ConstructPixelMapError(error, ERR_IMAGE_PIXELMAP_CREATE_FAILED, "read imageInfo fail");
2679         return nullptr;
2680     }
2681     if (IsYUV(imgInfo.pixelFormat)) {
2682 #ifdef EXT_PIXEL
2683         pixelMap = new(std::nothrow) PixelYuvExt();
2684 #else
2685         pixelMap = new(std::nothrow) PixelYuv();
2686 #endif
2687     } else {
2688         pixelMap = new(std::nothrow) PixelMap();
2689     }
2690 
2691     if (pixelMap == nullptr) {
2692         PixelMap::ConstructPixelMapError(error, ERR_IMAGE_PIXELMAP_CREATE_FAILED, "pixelmap create failed");
2693         return nullptr;
2694     }
2695 
2696     PixelMemInfo pixelMemInfo;
2697     if (!pixelMap->ReadPropertiesFromParcel(parcel, imgInfo, pixelMemInfo.allocatorType,
2698         pixelMemInfo.bufferSize, error)) {
2699         IMAGE_LOGE("read properties fail");
2700         delete pixelMap;
2701         return nullptr;
2702     }
2703     pixelMemInfo.isAstc = pixelMap->IsAstc();
2704     if (!ReadMemInfoFromParcel(parcel, pixelMemInfo, error)) {
2705         IMAGE_LOGE("read memInfo fail");
2706         delete pixelMap;
2707         return nullptr;
2708     }
2709     if (!UpdatePixelMapMemInfo(pixelMap, imgInfo, pixelMemInfo)) {
2710         IMAGE_LOGE("update pixelMap memInfo fail");
2711         delete pixelMap;
2712         return nullptr;
2713     }
2714     if (!pixelMap->ReadTransformData(parcel, pixelMap)) {
2715         IMAGE_LOGE("read transformData fail");
2716         delete pixelMap;
2717         return nullptr;
2718     }
2719     if (!pixelMap->ReadAstcRealSize(parcel, pixelMap)) {
2720         IMAGE_LOGE("read astcrealSize fail");
2721         delete pixelMap;
2722         return nullptr;
2723     }
2724     if (!pixelMap->ReadYuvDataInfoFromParcel(parcel, pixelMap)) {
2725         IMAGE_LOGE("ReadYuvDataInfoFromParcel fail");
2726         delete pixelMap;
2727         return nullptr;
2728     }
2729     return pixelMap;
2730 }
2731 
2732 // LCOV_EXCL_START
WriteUint8(std::vector<uint8_t> & buff,uint8_t value) const2733 void PixelMap::WriteUint8(std::vector<uint8_t> &buff, uint8_t value) const
2734 {
2735     buff.push_back(value);
2736 }
2737 
ReadUint8(std::vector<uint8_t> & buff,int32_t & cursor)2738 uint8_t PixelMap::ReadUint8(std::vector<uint8_t> &buff, int32_t &cursor)
2739 {
2740     if (static_cast<size_t>(cursor + 1) > buff.size()) {
2741         IMAGE_LOGE("ReadUint8 out of range");
2742         return TLV_END;
2743     }
2744     return buff[cursor++];
2745 }
2746 
GetVarintLen(int32_t value) const2747 uint8_t PixelMap::GetVarintLen(int32_t value) const
2748 {
2749     uint32_t uValue = static_cast<uint32_t>(value);
2750     uint8_t len = 1;
2751     while (uValue > TLV_VARINT_MASK) {
2752         len++;
2753         uValue >>= TLV_VARINT_BITS;
2754     }
2755     return len;
2756 }
2757 
WriteVarint(std::vector<uint8_t> & buff,int32_t value) const2758 void PixelMap::WriteVarint(std::vector<uint8_t> &buff, int32_t value) const
2759 {
2760     uint32_t uValue = uint32_t(value);
2761     while (uValue > TLV_VARINT_MASK) {
2762         buff.push_back(TLV_VARINT_MORE | uint8_t(uValue & TLV_VARINT_MASK));
2763         uValue >>= TLV_VARINT_BITS;
2764     }
2765     buff.push_back(uint8_t(uValue));
2766 }
2767 
ReadVarint(std::vector<uint8_t> & buff,int32_t & cursor)2768 int32_t PixelMap::ReadVarint(std::vector<uint8_t> &buff, int32_t &cursor)
2769 {
2770     uint32_t value = 0;
2771     uint8_t shift = 0;
2772     uint32_t item = 0;
2773     do {
2774         if (static_cast<size_t>(cursor + 1) > buff.size()) {
2775             IMAGE_LOGE("ReadVarint out of range");
2776             return static_cast<int32_t>(TLV_END);
2777         }
2778         item = uint32_t(buff[cursor++]);
2779         value |= (item & TLV_VARINT_MASK) << shift;
2780         shift += TLV_VARINT_BITS;
2781     } while ((item & TLV_VARINT_MORE) != 0);
2782     return int32_t(value);
2783 }
2784 
WriteData(std::vector<uint8_t> & buff,const uint8_t * data,const int32_t & height,const int32_t & rowDataSize,const int32_t & rowStride) const2785 void PixelMap::WriteData(std::vector<uint8_t> &buff, const uint8_t *data,
2786     const int32_t &height, const int32_t &rowDataSize, const int32_t &rowStride) const
2787 {
2788     if (data == nullptr) {
2789         IMAGE_LOGE("WriteData invalid input parameter: data is null");
2790         return;
2791     }
2792 
2793     if (allocatorType_ == AllocatorType::DMA_ALLOC) {
2794         for (int row = 0; row < height; row++) {
2795             for (int col = 0; col < rowDataSize; col++) {
2796                 buff.push_back(*(data + row * rowStride + col));
2797             }
2798         }
2799     } else {
2800         int32_t size = pixelsSize_;
2801         for (int32_t offset = 0; offset < size; offset++) {
2802             buff.push_back(*(data + offset));
2803         }
2804     }
2805 }
2806 
ReadData(std::vector<uint8_t> & buff,int32_t size,int32_t & cursor)2807 uint8_t *PixelMap::ReadData(std::vector<uint8_t> &buff, int32_t size, int32_t &cursor)
2808 {
2809     if (size <= 0) {
2810         IMAGE_LOGE("pixel map tlv read data fail: invalid size[%{public}d]", size);
2811         return nullptr;
2812     }
2813     if (static_cast<size_t>(cursor + size) > buff.size()) {
2814         IMAGE_LOGE("ReadData out of range");
2815         return nullptr;
2816     }
2817     uint8_t *data = static_cast<uint8_t *>(malloc(size));
2818     if (data == nullptr) {
2819         IMAGE_LOGE("pixel map tlv read data fail: malloc memory size[%{public}d]", size);
2820         return nullptr;
2821     }
2822     for (int32_t offset = 0; offset < size; offset++) {
2823         *(data + offset) = buff[cursor++];
2824     }
2825     return data;
2826 }
2827 
EncodeTlv(std::vector<uint8_t> & buff) const2828 bool PixelMap::EncodeTlv(std::vector<uint8_t> &buff) const
2829 {
2830     WriteUint8(buff, TLV_IMAGE_WIDTH);
2831     WriteVarint(buff, GetVarintLen(imageInfo_.size.width));
2832     WriteVarint(buff, imageInfo_.size.width);
2833     WriteUint8(buff, TLV_IMAGE_HEIGHT);
2834     WriteVarint(buff, GetVarintLen(imageInfo_.size.height));
2835     WriteVarint(buff, imageInfo_.size.height);
2836     WriteUint8(buff, TLV_IMAGE_PIXELFORMAT);
2837     WriteVarint(buff, GetVarintLen(static_cast<int32_t>(imageInfo_.pixelFormat)));
2838     WriteVarint(buff, static_cast<int32_t>(imageInfo_.pixelFormat));
2839     WriteUint8(buff, TLV_IMAGE_COLORSPACE);
2840     WriteVarint(buff, GetVarintLen(static_cast<int32_t>(imageInfo_.colorSpace)));
2841     WriteVarint(buff, static_cast<int32_t>(imageInfo_.colorSpace));
2842     WriteUint8(buff, TLV_IMAGE_ALPHATYPE);
2843     WriteVarint(buff, GetVarintLen(static_cast<int32_t>(imageInfo_.alphaType)));
2844     WriteVarint(buff, static_cast<int32_t>(imageInfo_.alphaType));
2845     WriteUint8(buff, TLV_IMAGE_BASEDENSITY);
2846     WriteVarint(buff, GetVarintLen(imageInfo_.baseDensity));
2847     WriteVarint(buff, imageInfo_.baseDensity);
2848     WriteUint8(buff, TLV_IMAGE_ALLOCATORTYPE);
2849     AllocatorType tmpAllocatorType = AllocatorType::HEAP_ALLOC;
2850     WriteVarint(buff, GetVarintLen(static_cast<int32_t>(tmpAllocatorType)));
2851     WriteVarint(buff, static_cast<int32_t>(tmpAllocatorType));
2852     WriteUint8(buff, TLV_IMAGE_DATA);
2853     const uint8_t *data = data_;
2854     uint64_t dataSize = static_cast<uint64_t>(rowDataSize_) * static_cast<uint64_t>(imageInfo_.size.height);
2855     if (isUnMap_ || data == nullptr || size_t(dataSize) > MAX_IMAGEDATA_SIZE || dataSize <= 0) {
2856         WriteVarint(buff, 0); // L is zero and no value
2857         WriteUint8(buff, TLV_END); // end tag
2858         IMAGE_LOGE("pixel map tlv encode fail: no data, isUnMap %{public}d", isUnMap_);
2859         return false;
2860     }
2861     WriteVarint(buff, static_cast<int32_t>(dataSize));
2862     WriteData(buff, data, imageInfo_.size.height, rowDataSize_, rowStride_);
2863     WriteUint8(buff, TLV_END); // end tag
2864     return true;
2865 }
2866 
ReadTlvAttr(std::vector<uint8_t> & buff,ImageInfo & info,int32_t & type,int32_t & size,uint8_t ** data)2867 void PixelMap::ReadTlvAttr(std::vector<uint8_t> &buff, ImageInfo &info, int32_t &type, int32_t &size, uint8_t **data)
2868 {
2869     int cursor = 0;
2870     for (uint8_t tag = ReadUint8(buff, cursor); tag != TLV_END; tag = ReadUint8(buff, cursor)) {
2871         int32_t len = ReadVarint(buff, cursor);
2872         if (len <= 0 || static_cast<size_t>(cursor + len) > buff.size()) {
2873             IMAGE_LOGE("ReadTlvAttr out of range");
2874             return;
2875         }
2876         switch (tag) {
2877             case TLV_IMAGE_WIDTH:
2878                 info.size.width = ReadVarint(buff, cursor);
2879                 break;
2880             case TLV_IMAGE_HEIGHT:
2881                 info.size.height = ReadVarint(buff, cursor);
2882                 break;
2883             case TLV_IMAGE_PIXELFORMAT:
2884                 info.pixelFormat = static_cast<PixelFormat>(ReadVarint(buff, cursor));
2885                 break;
2886             case TLV_IMAGE_COLORSPACE:
2887                 info.colorSpace = static_cast<ColorSpace>(ReadVarint(buff, cursor));
2888                 break;
2889             case TLV_IMAGE_ALPHATYPE:
2890                 info.alphaType = static_cast<AlphaType>(ReadVarint(buff, cursor));
2891                 break;
2892             case TLV_IMAGE_BASEDENSITY:
2893                 info.baseDensity = ReadVarint(buff, cursor);
2894                 break;
2895             case TLV_IMAGE_ALLOCATORTYPE:
2896                 type = ReadVarint(buff, cursor);
2897                 IMAGE_LOGI("pixel alloctype: %{public}d", type);
2898                 break;
2899             case TLV_IMAGE_DATA:
2900                 size = len;
2901                 if (data != nullptr) {
2902                     *data = ReadData(buff, size, cursor);
2903                 }
2904                 break;
2905             default:
2906                 cursor += len; // skip unknown tag
2907                 IMAGE_LOGW("pixel map tlv decode warn: unknown tag[%{public}d]", tag);
2908                 break;
2909         }
2910     }
2911 }
2912 
DecodeTlv(std::vector<uint8_t> & buff)2913 PixelMap *PixelMap::DecodeTlv(std::vector<uint8_t> &buff)
2914 {
2915     PixelMap *pixelMap = new(std::nothrow) PixelMap();
2916     if (pixelMap == nullptr) {
2917         IMAGE_LOGE("pixel map tlv decode fail: new PixelMap error");
2918         return nullptr;
2919     }
2920     ImageInfo imageInfo;
2921     int32_t dataSize = 0;
2922     uint8_t *data = nullptr;
2923     int32_t allocType = static_cast<int32_t>(AllocatorType::DEFAULT);
2924     ReadTlvAttr(buff, imageInfo, allocType, dataSize, &data);
2925     if (data == nullptr || allocType != static_cast<int32_t>(AllocatorType::HEAP_ALLOC)) {
2926         delete pixelMap;
2927         IMAGE_LOGE("pixel map tlv decode fail: no data or invalid allocType");
2928         return nullptr;
2929     }
2930     uint32_t ret = pixelMap->SetImageInfo(imageInfo);
2931     if (ret != SUCCESS) {
2932         free(data);
2933         delete pixelMap;
2934         IMAGE_LOGE("pixel map tlv decode fail: set image info error[%{public}d]", ret);
2935         return nullptr;
2936     }
2937     if (dataSize != pixelMap->GetByteCount()) {
2938         free(data);
2939         delete pixelMap;
2940         IMAGE_LOGE("pixel map tlv decode fail: dataSize not match");
2941         return nullptr;
2942     }
2943     pixelMap->SetPixelsAddr(data, nullptr, dataSize, static_cast<AllocatorType>(allocType), nullptr);
2944     return pixelMap;
2945 }
2946 
IsYuvFormat(PixelFormat format)2947 bool PixelMap::IsYuvFormat(PixelFormat format)
2948 {
2949     return format == PixelFormat::NV21 || format == PixelFormat::NV12 ||
2950         format == PixelFormat::YCBCR_P010 || format == PixelFormat::YCRCB_P010;
2951 }
2952 
IsYuvFormat() const2953 bool PixelMap::IsYuvFormat() const
2954 {
2955     return IsYuvFormat(imageInfo_.pixelFormat);
2956 }
2957 
AssignYuvDataOnType(PixelFormat format,int32_t width,int32_t height)2958 void PixelMap::AssignYuvDataOnType(PixelFormat format, int32_t width, int32_t height)
2959 {
2960     if (PixelMap::IsYuvFormat(format)) {
2961         yuvDataInfo_.yWidth = static_cast<uint32_t>(width);
2962         yuvDataInfo_.yHeight = static_cast<uint32_t>(height);
2963         yuvDataInfo_.yStride = static_cast<uint32_t>(width);
2964         yuvDataInfo_.uvWidth = static_cast<uint32_t>((width + 1) / NUM_2);
2965         yuvDataInfo_.uvHeight = static_cast<uint32_t>((height + 1) / NUM_2);
2966         yuvDataInfo_.yOffset = 0;
2967         yuvDataInfo_.uvOffset =  yuvDataInfo_.yHeight * yuvDataInfo_.yStride;
2968         if (GetAllocatorType() == AllocatorType::DMA_ALLOC) {
2969             yuvDataInfo_.uvStride = yuvDataInfo_.yStride;
2970         } else {
2971             yuvDataInfo_.uvStride = static_cast<uint32_t>((width + 1) / NUM_2 * NUM_2);
2972         }
2973     }
2974 }
2975 
UpdateYUVDataInfo(PixelFormat format,int32_t width,int32_t height,YUVStrideInfo & strides)2976 void PixelMap::UpdateYUVDataInfo(PixelFormat format, int32_t width, int32_t height, YUVStrideInfo &strides)
2977 {
2978     if (PixelMap::IsYuvFormat(format)) {
2979         yuvDataInfo_.yWidth = static_cast<uint32_t>(width);
2980         yuvDataInfo_.yHeight = static_cast<uint32_t>(height);
2981         yuvDataInfo_.yStride = static_cast<uint32_t>(strides.yStride);
2982         yuvDataInfo_.yOffset = strides.yOffset;
2983         yuvDataInfo_.uvStride = strides.uvStride;
2984         yuvDataInfo_.uvOffset = strides.uvOffset;
2985         yuvDataInfo_.uvWidth = static_cast<uint32_t>((width + 1) / NUM_2);
2986         yuvDataInfo_.uvHeight = static_cast<uint32_t>((height + 1) / NUM_2);
2987     }
2988 }
2989 
GetNamedAlphaType(const AlphaType alphaType)2990 static const string GetNamedAlphaType(const AlphaType alphaType)
2991 {
2992     switch (alphaType) {
2993         case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
2994             return "Alpha Type Unknown";
2995         case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
2996             return "Alpha Type Opaque";
2997         case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
2998             return "Alpha Type Premul";
2999         case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
3000             return "Alpha Type Unpremul";
3001         default:
3002             return "Alpha Type Unknown";
3003     }
3004     return "Alpha Type Unknown";
3005 }
3006 
GetNamedPixelFormat(const PixelFormat pixelFormat)3007 static const string GetNamedPixelFormat(const PixelFormat pixelFormat)
3008 {
3009     switch (pixelFormat) {
3010         case PixelFormat::UNKNOWN:
3011             return "Pixel Format UNKNOWN";
3012         case PixelFormat::RGB_565:
3013             return "Pixel Format RGB_565";
3014         case PixelFormat::RGB_888:
3015             return "Pixel Format RGB_888";
3016         case PixelFormat::NV21:
3017             return "Pixel Format NV21";
3018         case PixelFormat::NV12:
3019             return "Pixel Format NV12";
3020         case PixelFormat::YCBCR_P010:
3021             return "Pixel Format YCBCR_P010";
3022         case PixelFormat::YCRCB_P010:
3023             return "Pixel Format YCRCB_P010";
3024         case PixelFormat::CMYK:
3025             return "Pixel Format CMYK";
3026         case PixelFormat::ARGB_8888:
3027             return "Pixel Format ARGB_8888";
3028         case PixelFormat::ALPHA_8:
3029             return "Pixel Format ALPHA_8";
3030         case PixelFormat::RGBA_8888:
3031             return "Pixel Format RGBA_8888";
3032         case PixelFormat::BGRA_8888:
3033             return "Pixel Format BGRA_8888";
3034         case PixelFormat::RGBA_F16:
3035             return "Pixel Format RGBA_F16";
3036         case PixelFormat::ASTC_4x4:
3037             return "Pixel Format ASTC_4x4";
3038         case PixelFormat::ASTC_6x6:
3039             return "Pixel Format ASTC_6x6";
3040         case PixelFormat::ASTC_8x8:
3041             return "Pixel Format ASTC_8x8";
3042         case PixelFormat::RGBA_1010102:
3043             return "Pixel Format RGBA_1010102";
3044         default:
3045             return "Pixel Format UNKNOWN";
3046     }
3047     return "Pixel Format UNKNOWN";
3048 }
3049 
3050 constexpr uint8_t HALF_LOW_BYTE = 0;
3051 constexpr uint8_t HALF_HIGH_BYTE = 1;
3052 
HalfTranslate(const uint8_t * ui)3053 static float HalfTranslate(const uint8_t* ui)
3054 {
3055     return HalfToFloat(U8ToU16(ui[HALF_HIGH_BYTE], ui[HALF_LOW_BYTE]));
3056 }
3057 
HalfTranslate(const float pixel,uint8_t * ui)3058 static void HalfTranslate(const float pixel, uint8_t* ui)
3059 {
3060     uint16_t val = FloatToHalf(pixel);
3061     ui[HALF_LOW_BYTE] = static_cast<uint8_t>((val >> SHIFT_8_BIT) & UINT8_MAX);
3062     ui[HALF_HIGH_BYTE] = static_cast<uint8_t>(val & UINT8_MAX);
3063 }
3064 constexpr uint8_t RGBA_F16_R_OFFSET = 0;
3065 constexpr uint8_t RGBA_F16_G_OFFSET = 2;
3066 constexpr uint8_t RGBA_F16_B_OFFSET = 4;
3067 constexpr uint8_t RGBA_F16_A_OFFSET = 6;
3068 
3069 static constexpr float FLOAT_NUMBER_NEAR_ZERO = 0.000001;
3070 static constexpr float FLOAT_ZERO = 0.0f;
ProcessPremulF16Pixel(float mulPixel,float alpha,const float percent)3071 static float ProcessPremulF16Pixel(float mulPixel, float alpha, const float percent)
3072 {
3073     if (alpha < FLOAT_NUMBER_NEAR_ZERO && alpha > -FLOAT_NUMBER_NEAR_ZERO) {
3074         return FLOAT_ZERO;
3075     }
3076     float res = mulPixel * percent / alpha;
3077     return res > MAX_HALF ? MAX_HALF : res;
3078 }
3079 
SetF16PixelAlpha(uint8_t * pixel,const float percent,bool isPixelPremul)3080 static void SetF16PixelAlpha(uint8_t *pixel, const float percent, bool isPixelPremul)
3081 {
3082     if (pixel == nullptr) {
3083         IMAGE_LOGE("SetF16PixelAlpha invalid input parameter: pixel is null");
3084         return;
3085     }
3086 
3087     float a = HalfTranslate(pixel + RGBA_F16_A_OFFSET);
3088     if (isPixelPremul) {
3089         float r = HalfTranslate(pixel + RGBA_F16_R_OFFSET);
3090         float g = HalfTranslate(pixel + RGBA_F16_G_OFFSET);
3091         float b = HalfTranslate(pixel + RGBA_F16_B_OFFSET);
3092         r = ProcessPremulF16Pixel(r, a, percent);
3093         g = ProcessPremulF16Pixel(g, a, percent);
3094         b = ProcessPremulF16Pixel(b, a, percent);
3095         HalfTranslate(r, pixel + RGBA_F16_R_OFFSET);
3096         HalfTranslate(g, pixel + RGBA_F16_G_OFFSET);
3097         HalfTranslate(b, pixel + RGBA_F16_B_OFFSET);
3098     }
3099     a = percent * MAX_HALF;
3100     HalfTranslate(a, pixel + RGBA_F16_A_OFFSET);
3101 }
3102 
3103 static constexpr uint8_t U_ZERO = 0;
ProcessPremulPixel(uint8_t mulPixel,uint8_t alpha,const float percent)3104 static uint8_t ProcessPremulPixel(uint8_t mulPixel, uint8_t alpha, const float percent)
3105 {
3106     // mP = oP * oAlpha / UINT8_MAX
3107     // => oP = mP * UINT8_MAX / oAlpha
3108     // nP = oP * percent
3109     // => nP = mP * UINT8_MAX * percent / oAlpha
3110     if (alpha == 0) {
3111         return U_ZERO;
3112     }
3113     float nPixel = mulPixel * percent * UINT8_MAX / alpha;
3114     if ((nPixel + HALF_ONE) >= UINT8_MAX) {
3115         return UINT8_MAX;
3116     }
3117     return static_cast<uint8_t>(nPixel + HALF_ONE);
3118 }
3119 
SetUintPixelAlpha(uint8_t * pixel,const float percent,uint8_t pixelByte,int8_t alphaIndex,bool isPixelPremul)3120 static void SetUintPixelAlpha(uint8_t *pixel, const float percent,
3121     uint8_t pixelByte, int8_t alphaIndex, bool isPixelPremul)
3122 {
3123     if (pixel == nullptr) {
3124         IMAGE_LOGE("SetUintPixelAlpha invalid input parameter: pixel is null");
3125         return;
3126     }
3127 
3128     if (isPixelPremul) {
3129         for (int32_t pixelIndex = 0; pixelIndex < pixelByte; pixelIndex++) {
3130             if (pixelIndex != alphaIndex) {
3131                 pixel[pixelIndex] = ProcessPremulPixel(pixel[pixelIndex],
3132                     pixel[alphaIndex], percent);
3133             }
3134         }
3135     }
3136     pixel[alphaIndex] = static_cast<uint8_t>(UINT8_MAX * percent + HALF_ONE);
3137 }
3138 
3139 static constexpr uint8_t UINT2_MAX = 3;
3140 static constexpr uint16_t UINT10_MAX = 1023;
CheckPixel(uint16_t & pixel,uint16_t alpha,const float percent)3141 static void CheckPixel(uint16_t &pixel, uint16_t alpha, const float percent)
3142 {
3143     if (alpha != 0) {
3144         float rPixel = pixel * percent * UINT2_MAX / alpha;
3145         if ((rPixel + HALF_ONE) >= UINT10_MAX) {
3146             pixel = UINT10_MAX;
3147         }
3148         pixel = static_cast<uint16_t>(rPixel + HALF_ONE);
3149     } else {
3150         pixel = 0;
3151     }
3152 }
3153 
SetRGBA1010102PixelAlpha(uint8_t * src,const float percent,int8_t alphaIndex,bool isPixelPremul)3154 static void SetRGBA1010102PixelAlpha(uint8_t *src, const float percent, int8_t alphaIndex, bool isPixelPremul)
3155 {
3156     if (isPixelPremul) {
3157         uint16_t r = 0;
3158         uint16_t g = 0;
3159         uint16_t b = 0;
3160         uint16_t a = 0;
3161         a = (uint16_t)((src[NUM_3] >> NUM_6) & 0x03);
3162         uint16_t rHigh = (uint16_t)(src[0] & 0xFF);
3163         r = (rHigh) + ((uint16_t)(src[1] << NUM_8) & 0x300);
3164         CheckPixel(r, a, percent);
3165         uint16_t gHigh = (uint16_t)(src[1] & 0xFF);
3166         g = (gHigh >> NUM_2) + ((uint16_t)(src[NUM_2] << NUM_6) & 0x3C0);
3167         CheckPixel(g, a, percent);
3168         uint16_t bHigh = (uint16_t)(src[NUM_2] & 0xFF);
3169         b = (bHigh >> NUM_4) + ((uint16_t)(src[NUM_3] << NUM_4) & 0x3F0);
3170         CheckPixel(b, a, percent);
3171         a = static_cast<uint16_t>(UINT2_MAX * percent + HALF_ONE);
3172         src[0] = (uint8_t)(r);
3173         src[1] = (uint8_t)(g << NUM_2 | r >> NUM_8);
3174         src[NUM_2] = (uint8_t)(b << NUM_4 | g >> NUM_6);
3175         src[NUM_3] = (uint8_t)(a << NUM_6 | b >> NUM_4);
3176     } else {
3177         uint8_t alpha = static_cast<uint8_t>(UINT2_MAX * percent + HALF_ONE);
3178         src[alphaIndex] = static_cast<uint8_t>((src[alphaIndex] & 0x3F) | (alpha << NUM_6));
3179     }
3180 }
3181 
GetAlphaIndex(const PixelFormat & pixelFormat)3182 static int8_t GetAlphaIndex(const PixelFormat& pixelFormat)
3183 {
3184     switch (pixelFormat) {
3185         case PixelFormat::ARGB_8888:
3186         case PixelFormat::ALPHA_8:
3187             return ARGB_ALPHA_INDEX;
3188         case PixelFormat::RGBA_8888:
3189         case PixelFormat::BGRA_8888:
3190         case PixelFormat::RGBA_F16:
3191         case PixelFormat::RGBA_1010102:
3192             return BGRA_ALPHA_INDEX;
3193         default:
3194             return INVALID_ALPHA_INDEX;
3195     }
3196 }
3197 
ConvertUintPixelAlpha(uint8_t * rpixel,uint8_t pixelByte,int8_t alphaIndex,bool isPremul,uint8_t * wpixel)3198 static void ConvertUintPixelAlpha(uint8_t *rpixel,
3199     uint8_t pixelByte, int8_t alphaIndex, bool isPremul, uint8_t *wpixel)
3200 {
3201     if (rpixel == nullptr || wpixel == nullptr) {
3202         IMAGE_LOGE("ConvertUintPixelAlpha invalid input parameter: rpixel or wpixel is null");
3203         return;
3204     }
3205 
3206     float alphaValue = static_cast<float>(rpixel[alphaIndex]) / UINT8_MAX;
3207     for (int32_t pixelIndex = 0; pixelIndex < pixelByte; pixelIndex++) {
3208         float pixelValue = static_cast<float>(rpixel[pixelIndex]);
3209         if (pixelIndex != alphaIndex) {
3210             float nPixel;
3211             if (isPremul) {
3212                 nPixel = pixelValue * alphaValue;
3213             } else {
3214                 nPixel = (alphaValue > 0) ? pixelValue / alphaValue : 0;
3215             }
3216             wpixel[pixelIndex] = static_cast<uint8_t>(nPixel + HALF_ONE);
3217         } else {
3218             wpixel[pixelIndex] = rpixel[pixelIndex];
3219         }
3220     }
3221 }
3222 
CheckAlphaFormatInput(PixelMap & wPixelMap,const bool isPremul)3223 uint32_t PixelMap::CheckAlphaFormatInput(PixelMap &wPixelMap, const bool isPremul)
3224 {
3225     ImageInfo dstImageInfo;
3226     wPixelMap.GetImageInfo(dstImageInfo);
3227     uint32_t dstPixelSize = wPixelMap.GetCapacity();
3228     int32_t dstPixelBytes = wPixelMap.GetPixelBytes();
3229     void* dstData = wPixelMap.GetWritablePixels();
3230     int32_t stride = wPixelMap.GetRowStride();
3231 
3232     if (isUnMap_ || dstData == nullptr || data_ == nullptr) {
3233         IMAGE_LOGE("read pixels by dstPixelMap or srcPixelMap data is null, isUnMap %{public}d.", isUnMap_);
3234         return ERR_IMAGE_READ_PIXELMAP_FAILED;
3235     }
3236     if (!((GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_PREMUL && !isPremul) ||
3237         (GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL && isPremul))) {
3238         IMAGE_LOGE("alpha type error");
3239         return COMMON_ERR_INVALID_PARAMETER;
3240     }
3241     if (imageInfo_.size.height != dstImageInfo.size.height || imageInfo_.size.width != dstImageInfo.size.width) {
3242         IMAGE_LOGE("dstPixelMap size mismtach srcPixelMap");
3243         return COMMON_ERR_INVALID_PARAMETER;
3244     }
3245     if (stride != GetRowStride() || dstPixelSize < pixelsSize_) {
3246         IMAGE_LOGE("stride or pixelsSize from dstPixelMap mismtach srcPixelMap");
3247         return COMMON_ERR_INVALID_PARAMETER;
3248     }
3249 
3250     PixelFormat srcPixelFormat = GetPixelFormat();
3251     PixelFormat dstPixelFormat = dstImageInfo.pixelFormat;
3252     int8_t srcAlphaIndex = GetAlphaIndex(srcPixelFormat);
3253     int8_t dstAlphaIndex = GetAlphaIndex(dstPixelFormat);
3254     if (srcPixelFormat != dstPixelFormat || srcAlphaIndex == INVALID_ALPHA_INDEX ||
3255         dstAlphaIndex == INVALID_ALPHA_INDEX || srcPixelFormat == PixelFormat::RGBA_F16 ||
3256         dstPixelFormat == PixelFormat::RGBA_F16) {
3257         IMAGE_LOGE("Could not perform premultiply or nonpremultiply from %{public}s to %{public}s",
3258             GetNamedPixelFormat(srcPixelFormat).c_str(), GetNamedPixelFormat(dstPixelFormat).c_str());
3259         return ERR_IMAGE_DATA_UNSUPPORT;
3260     }
3261 
3262     if ((srcPixelFormat == PixelFormat::ALPHA_8 && pixelBytes_ != ALPHA_BYTES) ||
3263         (dstPixelFormat == PixelFormat::ALPHA_8 && dstPixelBytes != ALPHA_BYTES)) {
3264         IMAGE_LOGE("Pixel format %{public}s and %{public}s mismatch pixelByte %{public}d and %{public}d",
3265             GetNamedPixelFormat(srcPixelFormat).c_str(), GetNamedPixelFormat(dstPixelFormat).c_str(), pixelBytes_,
3266             dstPixelBytes);
3267         return COMMON_ERR_INVALID_PARAMETER;
3268     }
3269     return SUCCESS;
3270 }
3271 
ConvertAlphaFormat(PixelMap & wPixelMap,const bool isPremul)3272 uint32_t PixelMap::ConvertAlphaFormat(PixelMap &wPixelMap, const bool isPremul)
3273 {
3274     uint32_t res = CheckAlphaFormatInput(wPixelMap, isPremul);
3275     if (res != SUCCESS) {
3276         return res;
3277     }
3278 
3279     ImageInfo dstImageInfo;
3280     wPixelMap.GetImageInfo(dstImageInfo);
3281     void* dstData = wPixelMap.GetWritablePixels();
3282     int32_t stride = wPixelMap.GetRowStride();
3283 
3284     PixelFormat srcPixelFormat = GetPixelFormat();
3285     int8_t srcAlphaIndex = GetAlphaIndex(srcPixelFormat);
3286     int32_t index = 0;
3287     for (int32_t i = 0; i < imageInfo_.size.height; ++i) {
3288         for (int32_t j = 0; j < stride; j+=pixelBytes_) {
3289             index = i * stride + j;
3290             ConvertUintPixelAlpha(data_ + index, pixelBytes_, srcAlphaIndex, isPremul,
3291                 static_cast<uint8_t*>(dstData) + index);
3292         }
3293     }
3294     if (isPremul == true) {
3295         wPixelMap.SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
3296     } else {
3297         wPixelMap.SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
3298     }
3299     return SUCCESS;
3300 }
3301 
SetAlpha(const float percent)3302 uint32_t PixelMap::SetAlpha(const float percent)
3303 {
3304     auto alphaType = GetAlphaType();
3305     if (alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN || alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
3306         IMAGE_LOGE("Could not set alpha on %{public}s", GetNamedAlphaType(alphaType).c_str());
3307         return ERR_IMAGE_DATA_UNSUPPORT;
3308     }
3309 
3310     if (percent <= 0 || percent > 1) {
3311         IMAGE_LOGE("Set alpha input should (0 < input <= 1). Current input %{public}f", percent);
3312         return ERR_IMAGE_INVALID_PARAMETER;
3313     }
3314 
3315     bool isPixelPremul = alphaType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
3316     auto pixelFormat = GetPixelFormat();
3317     int32_t pixelsSize = GetByteCount();
3318     if (pixelsSize <= 0) {
3319         IMAGE_LOGE("Invalid byte count: %{public}d", pixelsSize);
3320         return ERR_IMAGE_INVALID_PARAMETER;
3321     }
3322     int8_t alphaIndex = GetAlphaIndex(pixelFormat);
3323     if (isUnMap_ || alphaIndex == INVALID_ALPHA_INDEX) {
3324         IMAGE_LOGE("Could not set alpha on %{public}s, isUnMap %{public}d",
3325             GetNamedPixelFormat(pixelFormat).c_str(), isUnMap_);
3326         return ERR_IMAGE_DATA_UNSUPPORT;
3327     }
3328 
3329     if ((pixelFormat == PixelFormat::ALPHA_8 && pixelBytes_ != ALPHA_BYTES) ||
3330         (pixelFormat == PixelFormat::RGBA_F16 && pixelBytes_ != RGBA_F16_BYTES)) {
3331         IMAGE_LOGE("Pixel format %{public}s mismatch pixelByte %{public}d",
3332             GetNamedPixelFormat(pixelFormat).c_str(), pixelBytes_);
3333         return ERR_IMAGE_INVALID_PARAMETER;
3334     }
3335 
3336     uint32_t uPixelsSize = static_cast<uint32_t>(pixelsSize);
3337     for (uint32_t i = 0; i < uPixelsSize; i += static_cast<uint32_t>(pixelBytes_)) {
3338         uint8_t* pixel = data_ + i;
3339         if (pixelFormat == PixelFormat::RGBA_F16) {
3340             SetF16PixelAlpha(pixel, percent, isPixelPremul);
3341         } else if (pixelFormat == PixelFormat::RGBA_1010102) {
3342             SetRGBA1010102PixelAlpha(pixel, percent, alphaIndex, isPixelPremul);
3343         } else {
3344             SetUintPixelAlpha(pixel, percent, pixelBytes_, alphaIndex, isPixelPremul);
3345         }
3346     }
3347     return SUCCESS;
3348 }
3349 
ToSkColorSpace(PixelMap * pixelmap)3350 static sk_sp<SkColorSpace> ToSkColorSpace(PixelMap *pixelmap)
3351 {
3352 #ifdef IMAGE_COLORSPACE_FLAG
3353     if (pixelmap == nullptr) {
3354         IMAGE_LOGE("ToSkColorSpace invalid input parameter: pixelmap is null");
3355         return nullptr;
3356     }
3357     if (pixelmap->InnerGetGrColorSpacePtr() == nullptr) {
3358         return nullptr;
3359     }
3360     return pixelmap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
3361 #else
3362     return nullptr;
3363 #endif
3364 }
3365 
ToSkImageInfo(ImageInfo & info,sk_sp<SkColorSpace> colorSpace)3366 static SkImageInfo ToSkImageInfo(ImageInfo &info, sk_sp<SkColorSpace> colorSpace)
3367 {
3368     SkColorType colorType = ImageTypeConverter::ToSkColorType(info.pixelFormat);
3369     SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(info.alphaType);
3370     IMAGE_LOGD("ToSkImageInfo w %{public}d, h %{public}d", info.size.width, info.size.height);
3371     IMAGE_LOGD(
3372         "ToSkImageInfo pf %{public}s, at %{public}s, skpf %{public}s, skat %{public}s",
3373         ImageTypeConverter::ToName(info.pixelFormat).c_str(),
3374         ImageTypeConverter::ToName(info.alphaType).c_str(),
3375         ImageTypeConverter::ToName(colorType).c_str(),
3376         ImageTypeConverter::ToName(alphaType).c_str()
3377     );
3378     return SkImageInfo::Make(info.size.width, info.size.height, colorType, alphaType, colorSpace);
3379 }
3380 
ToImageInfo(ImageInfo & info,SkImageInfo & skInfo,bool sizeOnly=true)3381 static void ToImageInfo(ImageInfo &info, SkImageInfo &skInfo, bool sizeOnly = true)
3382 {
3383     info.size.width = skInfo.width();
3384     info.size.height = skInfo.height();
3385     if (!sizeOnly) {
3386         info.alphaType = ImageTypeConverter::ToAlphaType(skInfo.alphaType());
3387         info.pixelFormat = ImageTypeConverter::ToPixelFormat(skInfo.colorType());
3388     }
3389 }
3390 
3391 struct SkTransInfo {
3392     SkRect r;
3393     SkImageInfo info;
3394     SkBitmap bitmap;
3395 };
3396 
3397 struct TransMemoryInfo {
3398     AllocatorType allocType;
3399     std::unique_ptr<AbsMemory> memory = nullptr;
3400 };
3401 
3402 constexpr float HALF = 0.5f;
3403 
FloatToInt(float a)3404 static inline int FloatToInt(float a)
3405 {
3406     return static_cast<int>(a + HALF);
3407 }
3408 
3409 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
GenSrcTransInfo(SkTransInfo & srcInfo,ImageInfo & imageInfo,PixelMap * pixelmap,sk_sp<SkColorSpace> colorSpace)3410 static void GenSrcTransInfo(SkTransInfo &srcInfo, ImageInfo &imageInfo, PixelMap* pixelmap,
3411     sk_sp<SkColorSpace> colorSpace)
3412 {
3413     srcInfo.r = SkRect::MakeIWH(imageInfo.size.width, imageInfo.size.height);
3414     srcInfo.info = ToSkImageInfo(imageInfo, colorSpace);
3415     uint64_t rowStride = srcInfo.info.minRowBytes();
3416     if (pixelmap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
3417         if (pixelmap->GetFd() == nullptr) {
3418             IMAGE_LOGE("GenSrcTransInfo get surfacebuffer failed");
3419         }
3420         SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(pixelmap->GetFd());
3421         rowStride = static_cast<uint64_t>(sbBuffer->GetStride());
3422     }
3423     srcInfo.bitmap.installPixels(srcInfo.info, static_cast<uint8_t *>(pixelmap->GetWritablePixels()), rowStride);
3424 }
3425 #else
GenSrcTransInfo(SkTransInfo & srcInfo,ImageInfo & imageInfo,uint8_t * pixels,sk_sp<SkColorSpace> colorSpace)3426 static void GenSrcTransInfo(SkTransInfo &srcInfo, ImageInfo &imageInfo, uint8_t* pixels,
3427     sk_sp<SkColorSpace> colorSpace)
3428 {
3429     srcInfo.r = SkRect::MakeIWH(imageInfo.size.width, imageInfo.size.height);
3430     srcInfo.info = ToSkImageInfo(imageInfo, colorSpace);
3431     srcInfo.bitmap.installPixels(srcInfo.info, pixels, srcInfo.info.minRowBytes());
3432 }
3433 #endif
3434 
GendstTransInfo(SkTransInfo & srcInfo,SkTransInfo & dstInfo,SkMatrix & matrix,TransMemoryInfo & memoryInfo)3435 static bool GendstTransInfo(SkTransInfo &srcInfo, SkTransInfo &dstInfo, SkMatrix &matrix,
3436     TransMemoryInfo &memoryInfo)
3437 {
3438     dstInfo.r = matrix.mapRect(srcInfo.r);
3439     int width = FloatToInt(dstInfo.r.width());
3440     int height = FloatToInt(dstInfo.r.height());
3441     if (matrix.isTranslate()) {
3442         width += dstInfo.r.fLeft;
3443         height += dstInfo.r.fTop;
3444     }
3445     dstInfo.info = srcInfo.info.makeWH(width, height);
3446     PixelFormat format = ImageTypeConverter::ToPixelFormat(srcInfo.info.colorType());
3447 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3448     Size desiredSize = {dstInfo.info.width(), dstInfo.info.height()};
3449     MemoryData memoryData = {nullptr, dstInfo.info.computeMinByteSize(), "Trans ImageData", desiredSize, format};
3450 #else
3451     MemoryData memoryData = {nullptr, dstInfo.info.computeMinByteSize(), "Trans ImageData"};
3452     memoryData.format = format;
3453 #endif
3454     std::unique_ptr<AbsMemory> dstMemory = MemoryManager::CreateMemory(memoryInfo.allocType, memoryData);
3455     if (dstMemory == nullptr) {
3456         IMAGE_LOGE("CreateMemory falied");
3457         return false;
3458     }
3459     memoryInfo.memory = std::move(dstMemory);
3460     if (memset_s(memoryInfo.memory->data.data, memoryInfo.memory->data.size,
3461         0, memoryInfo.memory->data.size) != 0) {
3462         memoryInfo.memory->Release();
3463         return false;
3464     }
3465 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3466     uint64_t rowStride = dstInfo.info.minRowBytes();
3467     if (memoryInfo.allocType == AllocatorType::DMA_ALLOC) {
3468         if (memoryInfo.memory->extend.data == nullptr) {
3469             IMAGE_LOGE("GendstTransInfo get surfacebuffer failed");
3470         }
3471         SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(memoryInfo.memory->extend.data);
3472         rowStride = static_cast<uint64_t>(sbBuffer->GetStride());
3473     }
3474     dstInfo.bitmap.installPixels(dstInfo.info, memoryInfo.memory->data.data, rowStride);
3475 #else
3476     dstInfo.bitmap.installPixels(dstInfo.info, memoryInfo.memory->data.data, dstInfo.info.minRowBytes());
3477 #endif
3478     return true;
3479 }
3480 
3481 struct TransInfos {
3482     SkMatrix matrix;
3483 };
3484 
IsSupportAntiAliasing(const ImageInfo & imageInfo,const AntiAliasingOption & option)3485 bool IsSupportAntiAliasing(const ImageInfo& imageInfo, const AntiAliasingOption &option)
3486 {
3487     return option != AntiAliasingOption::NONE && imageInfo.size.width <= ANTIALIASING_SIZE &&
3488             imageInfo.size.height <= ANTIALIASING_SIZE;
3489 }
3490 
ToSkSamplingOption(const AntiAliasingOption & option)3491 SkSamplingOptions ToSkSamplingOption(const AntiAliasingOption &option)
3492 {
3493     switch (option) {
3494         case AntiAliasingOption::NONE: return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
3495         case AntiAliasingOption::LOW: return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
3496         case AntiAliasingOption::MEDIUM: return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
3497         case AntiAliasingOption::HIGH: return SkSamplingOptions(SkCubicResampler { 1 / 3.0f, 1 / 3.0f });
3498         default: return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
3499     }
3500 }
3501 
DrawImage(bool rectStaysRect,const AntiAliasingOption & option,SkCanvas & canvas,sk_sp<SkImage> & skImage)3502 void DrawImage(bool rectStaysRect, const AntiAliasingOption &option, SkCanvas &canvas, sk_sp<SkImage> &skImage)
3503 {
3504     if (rectStaysRect) {
3505         SkRect skrect = SkRect::MakeXYWH(0, 0, skImage->width(), skImage->height());
3506         SkPaint paint;
3507         paint.setAntiAlias(true);
3508         canvas.drawImageRect(skImage, skrect, ToSkSamplingOption(option), &paint);
3509     } else {
3510         canvas.drawImage(skImage, FLOAT_ZERO, FLOAT_ZERO, ToSkSamplingOption(option));
3511     }
3512 }
3513 
DoTranslation(TransInfos & infos,const AntiAliasingOption & option)3514 bool PixelMap::DoTranslation(TransInfos &infos, const AntiAliasingOption &option)
3515 {
3516     std::lock_guard<std::mutex> lock(*translationMutex_);
3517     ImageInfo imageInfo;
3518     GetImageInfo(imageInfo);
3519     TransMemoryInfo dstMemory;
3520     // We dont know how custom alloc memory
3521     dstMemory.allocType = (allocatorType_ == AllocatorType::CUSTOM_ALLOC) ? AllocatorType::DEFAULT : allocatorType_;
3522     SkTransInfo src;
3523 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3524     GenSrcTransInfo(src, imageInfo, this, ToSkColorSpace(this));
3525 #else
3526     if (isUnMap_) {
3527         IMAGE_LOGE("DoTranslation falied, isUnMap %{public}d", isUnMap_);
3528         return false;
3529     }
3530     GenSrcTransInfo(src, imageInfo, data_, ToSkColorSpace(this));
3531 #endif
3532     SkTransInfo dst;
3533     if (!GendstTransInfo(src, dst, infos.matrix, dstMemory)) {
3534         IMAGE_LOGE("GendstTransInfo dstMemory falied");
3535         this->errorCode = IMAGE_RESULT_DECODE_FAILED;
3536         return false;
3537     }
3538     SkCanvas canvas(dst.bitmap);
3539     if (!infos.matrix.isTranslate()) {
3540         if (!EQUAL_TO_ZERO(dst.r.fLeft) || !EQUAL_TO_ZERO(dst.r.fTop)) {
3541             canvas.translate(-dst.r.fLeft, -dst.r.fTop);
3542         }
3543     }
3544     canvas.concat(infos.matrix);
3545     src.bitmap.setImmutable();
3546     auto skimage = SkImage::MakeFromBitmap(src.bitmap);
3547     if (skimage == nullptr) {
3548         IMAGE_LOGE("MakeFromBitmap failed with nullptr");
3549         dstMemory.memory->Release();
3550         this->errorCode = IMAGE_RESULT_TRANSFORM;
3551         return false;
3552     }
3553     DrawImage(infos.matrix.rectStaysRect(), option, canvas, skimage);
3554     ToImageInfo(imageInfo, dst.info);
3555     auto m = dstMemory.memory.get();
3556 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3557     if (allocatorType_ == AllocatorType::DMA_ALLOC && IsHdr()) {
3558         sptr<SurfaceBuffer> sourceSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (GetFd()));
3559         sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(m->extend.data));
3560         VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
3561     }
3562 #endif
3563     SetPixelsAddr(m->data.data, m->extend.data, m->data.size, m->GetType(), nullptr);
3564     SetImageInfo(imageInfo, true);
3565     ImageUtils::FlushSurfaceBuffer(this);
3566     return true;
3567 }
3568 
scale(float xAxis,float yAxis)3569 void PixelMap::scale(float xAxis, float yAxis)
3570 {
3571     ImageTrace imageTrace("PixelMap scale xAxis = %f, yAxis = %f", xAxis, yAxis);
3572     TransInfos infos;
3573     infos.matrix.setScale(xAxis, yAxis);
3574     if (!DoTranslation(infos)) {
3575         IMAGE_LOGE("scale falied");
3576     }
3577 }
3578 
scale(float xAxis,float yAxis,const AntiAliasingOption & option)3579 void PixelMap::scale(float xAxis, float yAxis, const AntiAliasingOption &option)
3580 {
3581     ImageTrace imageTrace("PixelMap scale with option");
3582     if (option == AntiAliasingOption::SLR) {
3583 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3584         auto start = std::chrono::high_resolution_clock::now();
3585         ImageInfo tmpInfo;
3586         GetImageInfo(tmpInfo);
3587         Size desiredSize;
3588         desiredSize.width = static_cast<int32_t>(imageInfo_.size.width * xAxis);
3589         desiredSize.height = static_cast<int32_t>(imageInfo_.size.height * yAxis);
3590 
3591         PostProc postProc;
3592         if (!postProc.ScalePixelMapWithSLR(desiredSize, *this)) {
3593             IMAGE_LOGE("PixelMap::scale SLR failed");
3594         }
3595         auto end = std::chrono::high_resolution_clock::now();
3596         auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
3597         IMAGE_LOGI("PixelMap::scale SLR %{public}d, srcSize: [%{public}d, %{public}d], "
3598             "dstSize: [%{public}d, %{public}d], cost: %{public}llu",
3599             uniqueId_, tmpInfo.size.width, tmpInfo.size.height,
3600             desiredSize.width, desiredSize.height, duration.count());
3601 #else
3602         IMAGE_LOGE("Scale SLR no support this platform");
3603 #endif
3604     } else {
3605         TransInfos infos;
3606         infos.matrix.setScale(xAxis, yAxis);
3607         bool fixPixelFormat = imageInfo_.pixelFormat == PixelFormat::BGRA_8888 && option == AntiAliasingOption::LOW;
3608         if (fixPixelFormat) {
3609         // Workaround to fix a color glitching issue under BGRA with LOW anti-aliasing
3610         imageInfo_.pixelFormat = PixelFormat::RGBA_8888;
3611         }
3612         if (!DoTranslation(infos, option)) {
3613             IMAGE_LOGE("scale falied");
3614         }
3615         if (fixPixelFormat) {
3616             imageInfo_.pixelFormat = PixelFormat::BGRA_8888;
3617         }
3618     }
3619 }
3620 
resize(float xAxis,float yAxis)3621 bool PixelMap::resize(float xAxis, float yAxis)
3622 {
3623     if (IsYUV(imageInfo_.pixelFormat)) {
3624         IMAGE_LOGE("resize temp disabled for YUV data");
3625         return true;
3626     }
3627     ImageTrace imageTrace("PixelMap resize");
3628     TransInfos infos;
3629     infos.matrix.setScale(xAxis, yAxis);
3630     if (!DoTranslation(infos)) {
3631         IMAGE_LOGE("resize falied");
3632         return false;
3633     }
3634     return true;
3635 }
3636 
translate(float xAxis,float yAxis)3637 void PixelMap::translate(float xAxis, float yAxis)
3638 {
3639     ImageTrace imageTrace("PixelMap translate");
3640     TransInfos infos;
3641     infos.matrix.setTranslate(xAxis, yAxis);
3642     if (!DoTranslation(infos)) {
3643         IMAGE_LOGE("translate falied");
3644     }
3645 }
3646 
rotate(float degrees)3647 void PixelMap::rotate(float degrees)
3648 {
3649     ImageTrace imageTrace("PixelMap rotate");
3650     TransInfos infos;
3651     infos.matrix.setRotate(degrees);
3652     if (!DoTranslation(infos)) {
3653         IMAGE_LOGE("rotate falied");
3654     }
3655 }
3656 
flip(bool xAxis,bool yAxis)3657 void PixelMap::flip(bool xAxis, bool yAxis)
3658 {
3659     ImageTrace imageTrace("PixelMap flip");
3660     if (xAxis == false && yAxis == false) {
3661         return;
3662     }
3663     scale(xAxis ? -1 : 1, yAxis ? -1 : 1);
3664 }
3665 
crop(const Rect & rect)3666 uint32_t PixelMap::crop(const Rect &rect)
3667 {
3668     ImageTrace imageTrace("PixelMap crop");
3669     ImageInfo imageInfo;
3670     GetImageInfo(imageInfo);
3671 
3672     SkTransInfo src;
3673 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3674     GenSrcTransInfo(src, imageInfo, this, ToSkColorSpace(this));
3675 #else
3676     if (isUnMap_) {
3677         IMAGE_LOGE("PixelMap::crop falied, isUnMap %{public}d", isUnMap_);
3678         return ERR_IMAGE_CROP;
3679     }
3680     GenSrcTransInfo(src, imageInfo, data_, ToSkColorSpace(this));
3681 #endif
3682     SkTransInfo dst;
3683     SkIRect dstIRect = SkIRect::MakeXYWH(rect.left, rect.top, rect.width, rect.height);
3684     dst.r = SkRect::Make(dstIRect);
3685     if (dst.r == src.r) {
3686         return SUCCESS;
3687     }
3688 
3689     if (!src.r.contains(dst.r)) {
3690         IMAGE_LOGE("Invalid crop rect");
3691         return ERR_IMAGE_CROP;
3692     }
3693     dst.info = src.info.makeWH(dstIRect.width(), dstIRect.height());
3694     Size desiredSize = {dst.info.width(), dst.info.height()};
3695     MemoryData memoryData = {nullptr, dst.info.computeMinByteSize(), "Trans ImageData", desiredSize,
3696                              imageInfo.pixelFormat};
3697     auto m = MemoryManager::CreateMemory(allocatorType_, memoryData);
3698     if (m == nullptr) {
3699         return ERR_IMAGE_CROP;
3700     }
3701     uint64_t rowStride = dst.info.minRowBytes();
3702 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3703     if (allocatorType_ == AllocatorType::DMA_ALLOC) {
3704         if (m->extend.data == nullptr) {
3705             IMAGE_LOGE("GendstTransInfo get surfacebuffer failed");
3706             return ERR_IMAGE_CROP;
3707         }
3708         rowStride = static_cast<uint64_t>(reinterpret_cast<SurfaceBuffer*>(m->extend.data)->GetStride());
3709     }
3710 #endif
3711     if (!src.bitmap.readPixels(dst.info, m->data.data, rowStride, dstIRect.fLeft, dstIRect.fTop)) {
3712         m->Release();
3713         IMAGE_LOGE("ReadPixels failed");
3714         return ERR_IMAGE_CROP;
3715     }
3716     ToImageInfo(imageInfo, dst.info);
3717     SetPixelsAddr(m->data.data, m->extend.data, m->data.size, m->GetType(), nullptr);
3718     SetImageInfo(imageInfo, true);
3719     return SUCCESS;
3720 }
3721 
3722 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
DecomposeImage(sptr<SurfaceBuffer> & hdr,sptr<SurfaceBuffer> & sdr,bool isSRGB=false)3723 static bool DecomposeImage(sptr<SurfaceBuffer>& hdr, sptr<SurfaceBuffer>& sdr, bool isSRGB = false)
3724 {
3725     ImageTrace imageTrace("PixelMap decomposeImage");
3726     VpeUtils::SetSbMetadataType(hdr, HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_SINGLE);
3727     VpeUtils::SetSbMetadataType(sdr, HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_DUAL);
3728     VpeUtils::SetSbColorSpaceType(sdr,
3729         isSRGB ? HDI::Display::Graphic::Common::V1_0::CM_SRGB_FULL : HDI::Display::Graphic::Common::V1_0::CM_P3_FULL);
3730     std::unique_ptr<VpeUtils> utils = std::make_unique<VpeUtils>();
3731     int32_t res = utils->ColorSpaceConverterImageProcess(hdr, sdr);
3732     if (res != VPE_ERROR_OK || sdr == nullptr) {
3733         return false;
3734     }
3735     return true;
3736 }
3737 #endif
3738 
SetToSdrColorSpaceIsSRGB(bool isSRGB)3739 void PixelMap::SetToSdrColorSpaceIsSRGB(bool isSRGB)
3740 {
3741     toSdrColorIsSRGB_ = isSRGB;
3742 }
3743 
GetToSdrColorSpaceIsSRGB()3744 bool PixelMap::GetToSdrColorSpaceIsSRGB()
3745 {
3746     return toSdrColorIsSRGB_;
3747 }
3748 
UnMap()3749 bool PixelMap::UnMap()
3750 {
3751 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
3752     if (allocatorType_ != AllocatorType::SHARE_MEM_ALLOC) {
3753         return false;
3754     }
3755     std::lock_guard<std::mutex> lock(*unmapMutex_);
3756     if (!isUnMap_) {
3757         unMapCount_++;
3758         isUnMap_ = true;
3759 
3760         if (data_ != nullptr) {
3761             ::munmap(data_, pixelsSize_);
3762             data_ = nullptr;
3763         }
3764     }
3765     return true;
3766 #else
3767     return false;
3768 #endif
3769 }
3770 
ReMap()3771 bool PixelMap::ReMap()
3772 {
3773 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
3774     if (allocatorType_ != AllocatorType::SHARE_MEM_ALLOC) {
3775         return false;
3776     }
3777     std::lock_guard<std::mutex> lock(*unmapMutex_);
3778     if (!isUnMap_) {
3779         return true;
3780     }
3781 
3782     int *fd = static_cast<int *>(context_);
3783     if (fd == nullptr) {
3784         return false;
3785     }
3786 
3787     void *ptr = ::mmap(nullptr, pixelsSize_, PROT_READ, MAP_SHARED, *fd, 0);
3788     if (ptr == MAP_FAILED) {
3789         return false;
3790     }
3791 
3792     data_ = (uint8_t *)ptr;
3793 
3794     isUnMap_ = false;
3795     return true;
3796 #else
3797     return false;
3798 #endif
3799 }
3800 
ToSdr()3801 uint32_t PixelMap::ToSdr()
3802 {
3803     ImageInfo imageInfo;
3804     GetImageInfo(imageInfo);
3805     PixelFormat outFormat = PixelFormat::RGBA_8888;
3806     if (imageInfo.pixelFormat == PixelFormat::YCBCR_P010) {
3807         outFormat = PixelFormat::NV12;
3808     } else if (imageInfo.pixelFormat == PixelFormat::YCRCB_P010) {
3809         outFormat = PixelFormat::NV21;
3810     }
3811     bool toSRGB = toSdrColorIsSRGB_;
3812     return ToSdr(outFormat, toSRGB);
3813 }
3814 
ToSdr(PixelFormat format,bool toSRGB)3815 uint32_t PixelMap::ToSdr(PixelFormat format, bool toSRGB)
3816 {
3817 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
3818     IMAGE_LOGI("tosdr is not supported");
3819     return ERR_MEDIA_INVALID_OPERATION;
3820 #else
3821     ImageTrace imageTrace("PixelMap ToSdr");
3822     if (allocatorType_ != AllocatorType::DMA_ALLOC || !IsHdr()) {
3823         IMAGE_LOGI("pixelmap is not support tosdr");
3824         return ERR_MEDIA_INVALID_OPERATION;
3825     }
3826     AllocatorType dstType = AllocatorType::DMA_ALLOC;
3827     ImageInfo imageInfo;
3828     GetImageInfo(imageInfo);
3829     SkImageInfo skInfo = ToSkImageInfo(imageInfo, ToSkColorSpace(this));
3830     MemoryData sdrData = {nullptr, skInfo.computeMinByteSize(), "Trans ImageData", imageInfo.size};
3831     PixelFormat outFormat = format;
3832     if (format != PixelFormat::NV12 && format != PixelFormat::NV21 && format != PixelFormat::RGBA_8888) {
3833         outFormat = PixelFormat::RGBA_8888;
3834     }
3835     sdrData.format = outFormat;
3836     auto sdrMemory = MemoryManager::CreateMemory(dstType, sdrData);
3837     if (sdrMemory == nullptr) {
3838         IMAGE_LOGI("sdr memory alloc failed.");
3839         return IMAGE_RESULT_GET_SURFAC_FAILED;
3840     }
3841     sptr<SurfaceBuffer> hdrSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (GetFd()));
3842     sptr<SurfaceBuffer> sdrSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(sdrMemory->extend.data));
3843     if (!DecomposeImage(hdrSurfaceBuffer, sdrSurfaceBuffer, toSRGB)) {
3844         sdrMemory->Release();
3845         IMAGE_LOGI("ToSdr decompose failed");
3846         return IMAGE_RESULT_GET_SURFAC_FAILED;
3847     }
3848     SetPixelsAddr(sdrMemory->data.data, sdrMemory->extend.data, sdrMemory->data.size, dstType, nullptr);
3849     imageInfo.pixelFormat = outFormat;
3850     SetImageInfo(imageInfo, true);
3851 #ifdef IMAGE_COLORSPACE_FLAG
3852     InnerSetColorSpace(OHOS::ColorManager::ColorSpace(toSRGB ? ColorManager::SRGB : ColorManager::DISPLAY_P3));
3853 #endif
3854     return SUCCESS;
3855 #endif
3856 }
3857 
3858 #ifdef IMAGE_COLORSPACE_FLAG
InnerSetColorSpace(const OHOS::ColorManager::ColorSpace & grColorSpace,bool direct)3859 void PixelMap::InnerSetColorSpace(const OHOS::ColorManager::ColorSpace &grColorSpace, bool direct)
3860 {
3861     if (direct) {
3862         grColorSpace_ = std::make_shared<OHOS::ColorManager::ColorSpace>(grColorSpace);
3863     } else {
3864         grColorSpace_ = std::make_shared<OHOS::ColorManager::ColorSpace>(grColorSpace.ToSkColorSpace(),
3865             grColorSpace.GetColorSpaceName());
3866     }
3867 }
3868 
InnerGetGrColorSpace()3869 OHOS::ColorManager::ColorSpace PixelMap::InnerGetGrColorSpace()
3870 {
3871     if (grColorSpace_ == nullptr) {
3872         grColorSpace_ =
3873             std::make_shared<OHOS::ColorManager::ColorSpace>(OHOS::ColorManager::ColorSpaceName::SRGB);
3874     }
3875     return *grColorSpace_;
3876 }
3877 
isSameColorSpace(const OHOS::ColorManager::ColorSpace & src,const OHOS::ColorManager::ColorSpace & dst)3878 static bool isSameColorSpace(const OHOS::ColorManager::ColorSpace &src,
3879     const OHOS::ColorManager::ColorSpace &dst)
3880 {
3881     auto skSrc = src.ToSkColorSpace();
3882     auto skDst = dst.ToSkColorSpace();
3883     return SkColorSpace::Equals(skSrc.get(), skDst.get());
3884 }
3885 
ApplyColorSpace(const OHOS::ColorManager::ColorSpace & grColorSpace)3886 uint32_t PixelMap::ApplyColorSpace(const OHOS::ColorManager::ColorSpace &grColorSpace)
3887 {
3888     auto grName = grColorSpace.GetColorSpaceName();
3889     if (grColorSpace_ != nullptr && isSameColorSpace(*grColorSpace_, grColorSpace)) {
3890         if (grColorSpace_->GetColorSpaceName() != grName) {
3891             InnerSetColorSpace(grColorSpace);
3892         }
3893         return SUCCESS;
3894     }
3895     ImageInfo imageInfo;
3896     GetImageInfo(imageInfo);
3897     // Build sk source infomation
3898     SkTransInfo src;
3899     src.info = ToSkImageInfo(imageInfo, ToSkColorSpace(this));
3900     uint64_t rowStride = src.info.minRowBytes();
3901     uint8_t* srcData = data_;
3902 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
3903     if (isUnMap_) {
3904         IMAGE_LOGE("PixelMap::ApplyColorSpace falied, isUnMap %{public}d", isUnMap_);
3905         return ERR_IMAGE_COLOR_CONVERT;
3906     }
3907     if (GetAllocatorType() == AllocatorType::DMA_ALLOC && GetFd() != nullptr) {
3908         SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(GetFd());
3909         rowStride = static_cast<uint64_t>(sbBuffer->GetStride());
3910     }
3911     srcData = static_cast<uint8_t *>(GetWritablePixels());
3912 #endif
3913     src.bitmap.installPixels(src.info, srcData, rowStride);
3914     // Build sk target infomation
3915     SkTransInfo dst;
3916     dst.info = ToSkImageInfo(imageInfo, grColorSpace.ToSkColorSpace());
3917     MemoryData memoryData = {nullptr, dst.info.computeMinByteSize(),
3918         "Trans ImageData", {dst.info.width(), dst.info.height()}, imageInfo.pixelFormat};
3919     auto m = MemoryManager::CreateMemory(allocatorType_, memoryData);
3920     if (m == nullptr) {
3921         IMAGE_LOGE("applyColorSpace CreateMemory failed");
3922         return ERR_IMAGE_COLOR_CONVERT;
3923     }
3924     // Transfor pixels by readPixels
3925     if (!src.bitmap.readPixels(dst.info, m->data.data, rowStride, 0, 0)) {
3926         m->Release();
3927         IMAGE_LOGE("ReadPixels failed");
3928         return ERR_IMAGE_COLOR_CONVERT;
3929     }
3930     // Restore target infomation into pixelmap
3931     ToImageInfo(imageInfo, dst.info);
3932     grColorSpace_ = std::make_shared<OHOS::ColorManager::ColorSpace>(dst.info.refColorSpace(), grName);
3933     SetPixelsAddr(m->data.data, m->extend.data, m->data.size, m->GetType(), nullptr);
3934     SetImageInfo(imageInfo, true);
3935     return SUCCESS;
3936 }
3937 #endif
3938 // LCOV_EXCL_STOP
3939 } // namespace Media
3940 } // namespace OHOS
3941