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