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