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