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