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