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 #include <iostream>
18 #include <unistd.h>
19
20 #include "image_log.h"
21 #include "image_system_properties.h"
22 #include "image_trace.h"
23 #include "image_type_converter.h"
24 #include "image_utils.h"
25 #include "memory_manager.h"
26 #include "include/core/SkBitmap.h"
27 #include "include/core/SkCanvas.h"
28 #include "include/core/SkImage.h"
29 #include "hitrace_meter.h"
30 #include "media_errors.h"
31 #include "pixel_convert_adapter.h"
32 #include "pixel_map_utils.h"
33 #include "post_proc.h"
34 #include "parcel.h"
35 #include "pubdef.h"
36 #include "image_mdk_common.h"
37
38 #ifndef _WIN32
39 #include "securec.h"
40 #else
41 #include "memory.h"
42 #endif
43
44 #ifdef IMAGE_PURGEABLE_PIXELMAP
45 #include "purgeable_resource_manager.h"
46 #endif
47
48 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
49 #include <sys/mman.h>
50 #include "ashmem.h"
51 #include "buffer_handle_parcel.h"
52 #include "ipc_file_descriptor.h"
53 #include "surface_buffer.h"
54 #endif
55
56 #undef LOG_DOMAIN
57 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
58
59 #undef LOG_TAG
60 #define LOG_TAG "PixelMap"
61
62 namespace OHOS {
63 namespace Media {
64 using namespace std;
65 constexpr int32_t MAX_DIMENSION = INT32_MAX >> 2;
66 constexpr uint8_t FOUR_BYTE_SHIFT = 2;
67 constexpr int8_t INVALID_ALPHA_INDEX = -1;
68 constexpr uint8_t ARGB_ALPHA_INDEX = 0;
69 constexpr uint8_t BGRA_ALPHA_INDEX = 3;
70 constexpr uint8_t ALPHA_BYTES = 1;
71 constexpr uint8_t BGRA_BYTES = 4;
72 constexpr uint8_t RGBA_F16_BYTES = 8;
73 constexpr uint8_t PER_PIXEL_LEN = 1;
74
75 constexpr uint8_t FILL_NUMBER = 3;
76 constexpr uint8_t ALIGN_NUMBER = 4;
77
78 static const uint8_t NUM_2 = 2;
79 static const uint8_t NUM_3 = 3;
80 static const uint8_t NUM_5 = 5;
81 static const uint8_t NUM_6 = 6;
82 static const uint8_t NUM_7 = 7;
83
84 constexpr int32_t ANTIALIASING_SIZE = 350;
85
86 std::atomic<uint32_t> PixelMap::currentId = 0;
87
~PixelMap()88 PixelMap::~PixelMap()
89 {
90 IMAGE_LOGD("PixelMap::~PixelMap_id:%{public}d", GetUniqueId());
91 FreePixelMap();
92 }
93
FreePixelMap()94 void PixelMap::FreePixelMap() __attribute__((no_sanitize("cfi")))
95 {
96 // remove PixelMap from purgeable LRU if it is purgeable PixelMap
97 #ifdef IMAGE_PURGEABLE_PIXELMAP
98 if (purgeableMemPtr_) {
99 PurgeableMem::PurgeableResourceManager::GetInstance().RemoveResource(purgeableMemPtr_);
100 purgeableMemPtr_.reset();
101 purgeableMemPtr_ = nullptr;
102 }
103 #endif
104
105 if (data_ == nullptr) {
106 return;
107 }
108
109 if (freePixelMapProc_ != nullptr) {
110 freePixelMapProc_(data_, context_, pixelsSize_);
111 }
112
113 switch (allocatorType_) {
114 case AllocatorType::HEAP_ALLOC: {
115 free(data_);
116 data_ = nullptr;
117 break;
118 }
119 case AllocatorType::CUSTOM_ALLOC: {
120 if (custFreePixelMap_ != nullptr) {
121 custFreePixelMap_(data_, context_, pixelsSize_);
122 }
123 data_ = nullptr;
124 context_ = nullptr;
125 break;
126 }
127 case AllocatorType::SHARE_MEM_ALLOC: {
128 ReleaseSharedMemory(data_, context_, pixelsSize_);
129 data_ = nullptr;
130 context_ = nullptr;
131 break;
132 }
133 case AllocatorType::DMA_ALLOC: {
134 #if !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
135 ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer*>(context_));
136 data_ = nullptr;
137 context_ = nullptr;
138 #endif
139 break;
140 }
141 default: {
142 IMAGE_LOGE("unknown allocator type:[%{public}d].", allocatorType_);
143 return;
144 }
145 }
146 }
147
ReleaseSharedMemory(void * addr,void * context,uint32_t size)148 void PixelMap::ReleaseSharedMemory(void *addr, void *context, uint32_t size)
149 {
150 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
151 int *fd = static_cast<int *>(context);
152 if (addr != nullptr) {
153 ::munmap(addr, size);
154 }
155 if (fd != nullptr) {
156 ::close(*fd);
157 delete fd;
158 }
159 #endif
160 }
161
SetFreePixelMapProc(CustomFreePixelMap func)162 void PixelMap::SetFreePixelMapProc(CustomFreePixelMap func)
163 {
164 freePixelMapProc_ = func;
165 }
166
SetTransformered(bool isTransformered)167 void PixelMap::SetTransformered(bool isTransformered)
168 {
169 std::unique_lock<std::mutex> lock(*transformMutex_);
170 isTransformered_ = isTransformered;
171 }
172
SetPixelsAddr(void * addr,void * context,uint32_t size,AllocatorType type,CustomFreePixelMap func)173 void PixelMap::SetPixelsAddr(void *addr, void *context, uint32_t size, AllocatorType type, CustomFreePixelMap func)
174 {
175 if (data_ != nullptr) {
176 IMAGE_LOGD("SetPixelsAddr release the existed data first");
177 FreePixelMap();
178 }
179 if (type == AllocatorType::SHARE_MEM_ALLOC && context == nullptr) {
180 IMAGE_LOGE("SetPixelsAddr error type %{public}d ", type);
181 }
182 data_ = static_cast<uint8_t *>(addr);
183 context_ = context;
184 pixelsSize_ = size;
185 allocatorType_ = type;
186 custFreePixelMap_ = func;
187 if (type == AllocatorType::DMA_ALLOC && rowDataSize_ != 0) {
188 UpdateImageInfo();
189 }
190 }
191
CheckPixelmap(std::unique_ptr<PixelMap> & pixelMap,ImageInfo & imageInfo)192 bool CheckPixelmap(std::unique_ptr<PixelMap> &pixelMap, ImageInfo &imageInfo)
193 {
194 if (pixelMap->SetImageInfo(imageInfo) != SUCCESS) {
195 IMAGE_LOGE("set image info fail");
196 return false;
197 }
198 uint32_t bufferSize = pixelMap->GetByteCount();
199 if (bufferSize == 0 || (pixelMap->GetAllocatorType() == AllocatorType::HEAP_ALLOC &&
200 bufferSize > PIXEL_MAP_MAX_RAM_SIZE)) {
201 IMAGE_LOGE("AllocSharedMemory parameter is zero");
202 return false;
203 }
204 return true;
205 }
206
Create(const uint32_t * colors,uint32_t colorLength,const InitializationOptions & opts)207 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, const InitializationOptions &opts)
208 {
209 IMAGE_LOGD("PixelMap::Create1 enter");
210 return Create(colors, colorLength, 0, opts.size.width, opts);
211 }
212
Create(const uint32_t * colors,uint32_t colorLength,int32_t offset,int32_t stride,const InitializationOptions & opts)213 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, int32_t offset, int32_t stride,
214 const InitializationOptions &opts)
215 {
216 IMAGE_LOGD("PixelMap::Create2 enter");
217 return Create(colors, colorLength, 0, opts.size.width, opts, false);
218 }
219
Create(const uint32_t * colors,uint32_t colorLength,int32_t offset,int32_t stride,const InitializationOptions & opts,bool useCustomFormat)220 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, int32_t offset, int32_t stride,
221 const InitializationOptions &opts, bool useCustomFormat)
222 {
223 int errorCode;
224 BUILD_PARAM info;
225 info.offset_ = offset;
226 info.stride_ = stride;
227 info.flag_ = useCustomFormat;
228 return Create(colors, colorLength, info, opts, errorCode);
229 }
230
MakePixelMap(void * dstPixels,int fd,std::unique_ptr<PixelMap> & dstPixelMap)231 static void MakePixelMap(void *dstPixels, int fd, std::unique_ptr<PixelMap> &dstPixelMap)
232 {
233 void *fdBuffer = new int32_t();
234 *static_cast<int32_t *>(fdBuffer) = fd;
235 uint32_t bufferSize = dstPixelMap->GetByteCount();
236 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
237 dstPixelMap->SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::SHARE_MEM_ALLOC, nullptr);
238 #else
239 dstPixelMap->SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
240 #endif
241 }
242
Create(const uint32_t * colors,uint32_t colorLength,BUILD_PARAM & info,const InitializationOptions & opts,int & errorCode)243 unique_ptr<PixelMap> PixelMap::Create(const uint32_t *colors, uint32_t colorLength, BUILD_PARAM &info,
244 const InitializationOptions &opts, int &errorCode)
245 {
246 int offset = info.offset_;
247 int32_t stride = info.stride_;
248 bool useCustomFormat = info.flag_;
249 if (!CheckParams(colors, colorLength, offset, stride, opts)) {
250 return nullptr;
251 }
252 unique_ptr<PixelMap> dstPixelMap = make_unique<PixelMap>();
253 if (dstPixelMap == nullptr) {
254 errorCode = IMAGE_RESULT_PLUGIN_REGISTER_FAILED;
255 return nullptr;
256 }
257 PixelFormat format = PixelFormat::BGRA_8888;
258 if (useCustomFormat) {
259 format = ((opts.srcPixelFormat == PixelFormat::UNKNOWN) ? PixelFormat::BGRA_8888 : opts.srcPixelFormat);
260 }
261 ImageInfo srcImageInfo =
262 MakeImageInfo(stride, opts.size.height, format, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
263 PixelFormat dstPixelFormat = (opts.pixelFormat == PixelFormat::UNKNOWN ? PixelFormat::RGBA_8888 : opts.pixelFormat);
264 AlphaType dstAlphaType =
265 (opts.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) ? AlphaType::IMAGE_ALPHA_TYPE_PREMUL : opts.alphaType;
266 dstAlphaType = ImageUtils::GetValidAlphaTypeByFormat(dstAlphaType, dstPixelFormat);
267 ImageInfo dstImageInfo = MakeImageInfo(opts.size.width, opts.size.height, dstPixelFormat, dstAlphaType);
268 if (!CheckPixelmap(dstPixelMap, dstImageInfo)) {
269 errorCode = IMAGE_RESULT_DATA_ABNORMAL;
270 return nullptr;
271 }
272 int fd = 0;
273 uint32_t bufferSize = dstPixelMap->GetByteCount();
274 void *dstPixels = AllocSharedMemory(bufferSize, fd, dstPixelMap->GetUniqueId());
275 if (dstPixels == nullptr) {
276 IMAGE_LOGE("allocate memory size %{public}u fail", bufferSize);
277 errorCode = IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST;
278 return nullptr;
279 }
280 Position dstPosition;
281 if (!PixelConvertAdapter::WritePixelsConvert(reinterpret_cast<const void *>(colors + offset),
282 static_cast<uint32_t>(stride) << FOUR_BYTE_SHIFT, srcImageInfo,
283 dstPixels, dstPosition, dstPixelMap->GetRowBytes(), dstImageInfo)) {
284 IMAGE_LOGE("pixel convert in adapter failed.");
285 ReleaseBuffer(AllocatorType::SHARE_MEM_ALLOC, fd, bufferSize, &dstPixels);
286 dstPixels = nullptr;
287 errorCode = IMAGE_RESULT_THIRDPART_SKIA_ERROR;
288 return nullptr;
289 }
290 dstPixelMap->SetEditable(opts.editable);
291 MakePixelMap(dstPixels, fd, dstPixelMap);
292 ImageUtils::DumpPixelMapIfDumpEnabled(dstPixelMap);
293 return dstPixelMap;
294 }
295
ReleaseBuffer(AllocatorType allocatorType,int fd,uint64_t dataSize,void ** buffer)296 void PixelMap::ReleaseBuffer(AllocatorType allocatorType, int fd, uint64_t dataSize, void **buffer)
297 {
298 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
299 if (allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
300 if (*buffer != nullptr) {
301 ::munmap(*buffer, dataSize);
302 ::close(fd);
303 }
304 return;
305 }
306 #endif
307
308 if (allocatorType == AllocatorType::HEAP_ALLOC) {
309 if (*buffer != nullptr) {
310 free(*buffer);
311 *buffer = nullptr;
312 }
313 return;
314 }
315 }
316
AllocSharedMemory(const uint64_t bufferSize,int & fd,uint32_t uniqueId)317 void *PixelMap::AllocSharedMemory(const uint64_t bufferSize, int &fd, uint32_t uniqueId)
318 {
319 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
320 std::string name = "PixelMap RawData, uniqueId: " + std::to_string(getpid()) + '_' + std::to_string(uniqueId);
321 fd = AshmemCreate(name.c_str(), bufferSize);
322 if (fd < 0) {
323 IMAGE_LOGE("AllocSharedMemory fd error");
324 return nullptr;
325 }
326 int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
327 if (result < 0) {
328 IMAGE_LOGE("AshmemSetProt error");
329 ::close(fd);
330 return nullptr;
331 }
332 void* ptr = ::mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
333 if (ptr == MAP_FAILED) {
334 IMAGE_LOGE("mmap error, errno: %{public}s, fd %{public}d, bufferSize %{public}lld",
335 strerror(errno), fd, (long long)bufferSize);
336 ::close(fd);
337 return nullptr;
338 }
339 return ptr;
340 #else
341 return malloc(bufferSize);
342 #endif
343 }
344
CheckParams(const uint32_t * colors,uint32_t colorLength,int32_t offset,int32_t stride,const InitializationOptions & opts)345 bool PixelMap::CheckParams(const uint32_t *colors, uint32_t colorLength, int32_t offset, int32_t stride,
346 const InitializationOptions &opts)
347 {
348 if (colors == nullptr || colorLength <= 0) {
349 IMAGE_LOGE("colors invalid");
350 return false;
351 }
352 int32_t dstWidth = opts.size.width;
353 int32_t dstHeight = opts.size.height;
354 if (dstWidth <= 0 || dstHeight <= 0) {
355 IMAGE_LOGE("initial options size invalid");
356 return false;
357 }
358 if (stride < dstWidth) {
359 IMAGE_LOGE("stride: %{public}d must >= width: %{public}d", stride, dstWidth);
360 return false;
361 }
362 if (stride > MAX_DIMENSION) {
363 IMAGE_LOGE("stride %{public}d is out of range", stride);
364 return false;
365 }
366 int64_t lastLine = static_cast<int64_t>(dstHeight - 1) * stride + offset;
367 if (offset < 0 || static_cast<int64_t>(offset) + dstWidth > colorLength || lastLine + dstWidth > colorLength) {
368 IMAGE_LOGE("colors length: %{public}u, offset: %{public}d, stride: %{public}d is invalid",
369 colorLength, offset, stride);
370 return false;
371 }
372 return true;
373 }
374
Create(const InitializationOptions & opts)375 unique_ptr<PixelMap> PixelMap::Create(const InitializationOptions &opts)
376 {
377 IMAGE_LOGD("PixelMap::Create3 enter");
378 unique_ptr<PixelMap> dstPixelMap = make_unique<PixelMap>();
379 if (dstPixelMap == nullptr) {
380 IMAGE_LOGE("create pixelMap pointer fail");
381 return nullptr;
382 }
383 PixelFormat dstPixelFormat = (opts.pixelFormat == PixelFormat::UNKNOWN ? PixelFormat::RGBA_8888 : opts.pixelFormat);
384 AlphaType dstAlphaType =
385 (opts.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) ? AlphaType::IMAGE_ALPHA_TYPE_PREMUL : opts.alphaType;
386 dstAlphaType = ImageUtils::GetValidAlphaTypeByFormat(dstAlphaType, dstPixelFormat);
387 ImageInfo dstImageInfo = MakeImageInfo(opts.size.width, opts.size.height, dstPixelFormat, dstAlphaType);
388 if (dstPixelMap->SetImageInfo(dstImageInfo) != SUCCESS) {
389 IMAGE_LOGE("set image info fail");
390 return nullptr;
391 }
392 uint32_t bufferSize = dstPixelMap->GetByteCount();
393 if (bufferSize == 0) {
394 IMAGE_LOGE("calloc parameter bufferSize:[%{public}d] error.", bufferSize);
395 return nullptr;
396 }
397 int fd = 0;
398 void *dstPixels = AllocSharedMemory(bufferSize, fd, dstPixelMap->GetUniqueId());
399 if (dstPixels == nullptr) {
400 IMAGE_LOGE("allocate memory size %{public}u fail", bufferSize);
401 return nullptr;
402 }
403 // update alpha opaque
404 UpdatePixelsAlpha(dstImageInfo.alphaType, dstImageInfo.pixelFormat,
405 static_cast<uint8_t *>(dstPixels), *dstPixelMap.get());
406 void *fdBuffer = new int32_t();
407 *static_cast<int32_t *>(fdBuffer) = fd;
408 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
409 dstPixelMap->SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::SHARE_MEM_ALLOC, nullptr);
410 #else
411 dstPixelMap->SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
412 #endif
413 dstPixelMap->SetEditable(opts.editable);
414 return dstPixelMap;
415 }
416
UpdatePixelsAlpha(const AlphaType & alphaType,const PixelFormat & pixelFormat,uint8_t * dstPixels,PixelMap dstPixelMap)417 void PixelMap::UpdatePixelsAlpha(const AlphaType &alphaType, const PixelFormat &pixelFormat, uint8_t *dstPixels,
418 PixelMap dstPixelMap)
419 {
420 if (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
421 int8_t alphaIndex = -1;
422 if (pixelFormat == PixelFormat::RGBA_8888 || pixelFormat == PixelFormat::BGRA_8888) {
423 alphaIndex = BGRA_ALPHA_INDEX;
424 } else if (pixelFormat == PixelFormat::ARGB_8888) {
425 alphaIndex = 0;
426 }
427 if (alphaIndex != -1) {
428 uint8_t pixelBytes = dstPixelMap.GetPixelBytes();
429 uint32_t bufferSize = dstPixelMap.GetByteCount();
430 uint32_t i = alphaIndex;
431 while (i < bufferSize) {
432 dstPixels[i] = ALPHA_OPAQUE;
433 i += pixelBytes;
434 }
435 }
436 }
437 }
438
BuildPixelMap(unique_ptr<PixelMap> & dstPixelMap,const CropValue & cropType,ImageInfo & dstImageInfo,const Rect & sRect,const ImageInfo & srcImageInfo)439 static int32_t BuildPixelMap(unique_ptr<PixelMap> &dstPixelMap, const CropValue &cropType,
440 ImageInfo &dstImageInfo, const Rect &sRect, const ImageInfo &srcImageInfo)
441 {
442 dstPixelMap = make_unique<PixelMap>();
443 if (dstPixelMap == nullptr) {
444 IMAGE_LOGE("create pixelmap pointer fail");
445 return IMAGE_RESULT_PLUGIN_REGISTER_FAILED;
446 }
447
448 if (cropType == CropValue::VALID) {
449 dstImageInfo.size.width = sRect.width;
450 dstImageInfo.size.height = sRect.height;
451 } else {
452 dstImageInfo.size = srcImageInfo.size;
453 }
454 if (dstPixelMap->SetImageInfo(dstImageInfo) != SUCCESS) {
455 return IMAGE_RESULT_DATA_ABNORMAL;
456 }
457 return SUCCESS;
458 }
459
Create(PixelMap & source,const InitializationOptions & opts)460 unique_ptr<PixelMap> PixelMap::Create(PixelMap &source, const InitializationOptions &opts)
461 {
462 IMAGE_LOGD("PixelMap::Create4 enter");
463 Rect rect;
464 return Create(source, rect, opts);
465 }
466
Create(PixelMap & source,const Rect & srcRect,const InitializationOptions & opts)467 unique_ptr<PixelMap> PixelMap::Create(PixelMap &source, const Rect &srcRect, const InitializationOptions &opts)
468 {
469 int error;
470 return Create(source, srcRect, opts, error);
471 }
472
Create(PixelMap & source,const Rect & srcRect,const InitializationOptions & opts,int32_t & errorCode)473 unique_ptr<PixelMap> PixelMap::Create(PixelMap &source, const Rect &srcRect, const InitializationOptions &opts,
474 int32_t &errorCode)
475 {
476 IMAGE_LOGD("PixelMap::Create5 enter");
477 ImageInfo srcImageInfo;
478 source.GetImageInfo(srcImageInfo);
479 PostProc postProc;
480 Rect sRect = srcRect;
481 CropValue cropType = PostProc::ValidCropValue(sRect, srcImageInfo.size);
482 if (cropType == CropValue::INVALID) {
483 IMAGE_LOGE("src crop range is invalid");
484 errorCode = IMAGE_RESULT_DECODE_FAILED;
485 return nullptr;
486 }
487 ImageInfo dstImageInfo;
488 InitDstImageInfo(opts, srcImageInfo, dstImageInfo);
489 Size targetSize = dstImageInfo.size;
490 // use source if match
491 bool isHasConvert = postProc.HasPixelConvert(srcImageInfo, dstImageInfo);
492 if (opts.useSourceIfMatch && !source.IsEditable() && !opts.editable && (cropType == CropValue::NOCROP) &&
493 !isHasConvert && IsSameSize(srcImageInfo.size, dstImageInfo.size)) {
494 source.useSourceAsResponse_ = true;
495 return unique_ptr<PixelMap>(&source);
496 }
497 unique_ptr<PixelMap> dstPixelMap = nullptr;
498 if ((errorCode = BuildPixelMap(dstPixelMap, cropType, dstImageInfo, sRect, srcImageInfo)) != SUCCESS) {
499 return nullptr;
500 }
501 // dst pixelmap is source crop and convert pixelmap
502 if ((cropType == CropValue::VALID) || isHasConvert) {
503 if (!SourceCropAndConvert(source, srcImageInfo, dstImageInfo, sRect, *dstPixelMap.get())) {
504 return nullptr;
505 }
506 } else {
507 // only maybe size changed, copy source as scale operation
508 if (!CopyPixelMap(source, *dstPixelMap.get(), errorCode)) {
509 return nullptr;
510 }
511 }
512 if (!ScalePixelMap(targetSize, dstImageInfo.size, opts.scaleMode, *dstPixelMap.get())) {
513 return nullptr;
514 }
515 dstPixelMap->SetEditable(opts.editable);
516 ImageUtils::DumpPixelMapIfDumpEnabled(dstPixelMap);
517 return dstPixelMap;
518 }
519
SourceCropAndConvert(PixelMap & source,const ImageInfo & srcImageInfo,const ImageInfo & dstImageInfo,const Rect & srcRect,PixelMap & dstPixelMap)520 bool PixelMap::SourceCropAndConvert(PixelMap &source, const ImageInfo &srcImageInfo, const ImageInfo &dstImageInfo,
521 const Rect &srcRect, PixelMap &dstPixelMap)
522 {
523 uint32_t bufferSize = dstPixelMap.GetByteCount();
524 if (bufferSize == 0 || (source.GetAllocatorType() == AllocatorType::HEAP_ALLOC &&
525 bufferSize > PIXEL_MAP_MAX_RAM_SIZE)) {
526 IMAGE_LOGE("SourceCropAndConvert parameter bufferSize:[%{public}d] error.", bufferSize);
527 return false;
528 }
529 int fd = 0;
530 void *dstPixels = nullptr;
531 if (source.GetAllocatorType() == AllocatorType::SHARE_MEM_ALLOC) {
532 dstPixels = AllocSharedMemory(bufferSize, fd, dstPixelMap.GetUniqueId());
533 } else {
534 dstPixels = malloc(bufferSize);
535 }
536 if (dstPixels == nullptr) {
537 IMAGE_LOGE("source crop allocate memory fail allocatetype: %{public}d ", source.GetAllocatorType());
538 return false;
539 }
540
541 if (memset_s(dstPixels, bufferSize, 0, bufferSize) != EOK) {
542 IMAGE_LOGE("dstPixels memset_s failed.");
543 }
544 Position srcPosition { srcRect.left, srcRect.top };
545 if (!PixelConvertAdapter::ReadPixelsConvert(source.GetPixels(), srcPosition, source.GetRowStride(), srcImageInfo,
546 dstPixels, dstPixelMap.GetRowStride(), dstImageInfo)) {
547 IMAGE_LOGE("pixel convert in adapter failed.");
548 ReleaseBuffer(fd > 0 ? AllocatorType::SHARE_MEM_ALLOC : AllocatorType::HEAP_ALLOC, fd, bufferSize, &dstPixels);
549 return false;
550 }
551
552 if (fd <= 0) {
553 dstPixelMap.SetPixelsAddr(dstPixels, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
554 return true;
555 }
556 void *fdBuffer = new int32_t();
557 *static_cast<int32_t *>(fdBuffer) = fd;
558 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
559 dstPixelMap.SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::SHARE_MEM_ALLOC, nullptr);
560 #else
561 dstPixelMap.SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
562 #endif
563 return true;
564 }
565
ScalePixelMap(const Size & targetSize,const Size & dstSize,const ScaleMode & scaleMode,PixelMap & dstPixelMap)566 bool PixelMap::ScalePixelMap(const Size &targetSize, const Size &dstSize, const ScaleMode &scaleMode,
567 PixelMap &dstPixelMap)
568 {
569 if (dstSize.width == targetSize.width && dstSize.height == targetSize.height) {
570 return true;
571 }
572 PostProc postProc;
573 if (scaleMode == ScaleMode::FIT_TARGET_SIZE) {
574 if (!postProc.ScalePixelMap(targetSize, dstPixelMap)) {
575 IMAGE_LOGE("scale FIT_TARGET_SIZE fail");
576 return false;
577 }
578 }
579 if (scaleMode == ScaleMode::CENTER_CROP) {
580 if (!postProc.CenterScale(targetSize, dstPixelMap)) {
581 IMAGE_LOGE("scale CENTER_CROP fail");
582 return false;
583 }
584 }
585 return true;
586 }
587
InitDstImageInfo(const InitializationOptions & opts,const ImageInfo & srcImageInfo,ImageInfo & dstImageInfo)588 void PixelMap::InitDstImageInfo(const InitializationOptions &opts, const ImageInfo &srcImageInfo,
589 ImageInfo &dstImageInfo)
590 {
591 dstImageInfo.size = opts.size;
592 if (dstImageInfo.size.width == 0 && dstImageInfo.size.height == 0) {
593 dstImageInfo.size = srcImageInfo.size;
594 }
595 dstImageInfo.pixelFormat = opts.pixelFormat;
596 if (dstImageInfo.pixelFormat == PixelFormat::UNKNOWN) {
597 dstImageInfo.pixelFormat = srcImageInfo.pixelFormat;
598 }
599 dstImageInfo.alphaType = opts.alphaType;
600 if (dstImageInfo.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
601 dstImageInfo.alphaType = srcImageInfo.alphaType;
602 }
603 }
604
CopyPixMapToDst(PixelMap & source,void * & dstPixels,int & fd,uint32_t bufferSize)605 bool PixelMap::CopyPixMapToDst(PixelMap &source, void* &dstPixels, int &fd, uint32_t bufferSize)
606 {
607 if (source.GetAllocatorType() == AllocatorType::DMA_ALLOC) {
608 ImageInfo imageInfo;
609 source.GetImageInfo(imageInfo);
610 for (int i = 0; i < imageInfo.size.height; ++i) {
611 errno_t ret = memcpy_s(dstPixels, source.GetRowBytes(),
612 source.GetPixels() + i * source.GetRowStride(), source.GetRowBytes());
613 if (ret != 0) {
614 IMAGE_LOGE("copy source memory size %{public}u fail", bufferSize);
615 ReleaseBuffer(AllocatorType::DMA_ALLOC, fd, bufferSize, &dstPixels);
616 return false;
617 }
618 // Move the destination buffer pointer to the next row
619 dstPixels = reinterpret_cast<uint8_t *>(dstPixels) + source.GetRowBytes();
620 }
621 } else {
622 if (memcpy_s(dstPixels, bufferSize, source.GetPixels(), bufferSize) != 0) {
623 IMAGE_LOGE("copy source memory size %{public}u fail", bufferSize);
624 ReleaseBuffer(fd > 0 ? AllocatorType::SHARE_MEM_ALLOC : AllocatorType::HEAP_ALLOC,
625 fd, bufferSize, &dstPixels);
626 return false;
627 }
628 }
629 return true;
630 }
631
CopyPixelMap(PixelMap & source,PixelMap & dstPixelMap)632 bool PixelMap::CopyPixelMap(PixelMap &source, PixelMap &dstPixelMap)
633 {
634 int32_t error;
635 return CopyPixelMap(source, dstPixelMap, error);
636 }
CopyPixelMap(PixelMap & source,PixelMap & dstPixelMap,int32_t & error)637 bool PixelMap::CopyPixelMap(PixelMap &source, PixelMap &dstPixelMap, int32_t &error)
638 {
639 uint32_t bufferSize = source.GetByteCount();
640 if (source.GetPixels() == nullptr) {
641 IMAGE_LOGE("source pixelMap data invalid");
642 error = IMAGE_RESULT_GET_DATA_ABNORMAL;
643 return false;
644 }
645 if (bufferSize == 0 || (source.GetAllocatorType() == AllocatorType::HEAP_ALLOC &&
646 bufferSize > PIXEL_MAP_MAX_RAM_SIZE)) {
647 IMAGE_LOGE("AllocSharedMemory parameter bufferSize:[%{public}d] error.", bufferSize);
648 error = IMAGE_RESULT_DATA_ABNORMAL;
649 return false;
650 }
651 int fd = 0;
652 void *dstPixels = nullptr;
653 if (source.GetAllocatorType() == AllocatorType::SHARE_MEM_ALLOC) {
654 dstPixels = AllocSharedMemory(bufferSize, fd, dstPixelMap.GetUniqueId());
655 } else {
656 dstPixels = malloc(bufferSize);
657 }
658 if (dstPixels == nullptr) {
659 IMAGE_LOGE("source crop allocate memory fail allocatetype: %{public}d ", source.GetAllocatorType());
660 error = IMAGE_RESULT_MALLOC_ABNORMAL;
661 return false;
662 }
663 void* tmpDstPixels = dstPixels;
664 if (!CopyPixMapToDst(source, tmpDstPixels, fd, bufferSize)) {
665 error = IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL;
666 return false;
667 }
668 if (fd <= 0) {
669 dstPixelMap.SetPixelsAddr(dstPixels, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
670 return true;
671 }
672 void *fdBuffer = new int32_t();
673 *static_cast<int32_t *>(fdBuffer) = fd;
674 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
675 dstPixelMap.SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::SHARE_MEM_ALLOC, nullptr);
676 #else
677 dstPixelMap.SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
678 #endif
679 return true;
680 }
681
IsSameSize(const Size & src,const Size & dst)682 bool PixelMap::IsSameSize(const Size &src, const Size &dst)
683 {
684 return (src.width == dst.width) && (src.height == dst.height);
685 }
686
GetPixelFormatDetail(const PixelFormat format)687 bool PixelMap::GetPixelFormatDetail(const PixelFormat format)
688 {
689 switch (format) {
690 case PixelFormat::RGBA_8888: {
691 pixelBytes_ = ARGB_8888_BYTES;
692 colorProc_ = RGBA8888ToARGB;
693 break;
694 }
695 case PixelFormat::BGRA_8888: {
696 pixelBytes_ = ARGB_8888_BYTES;
697 colorProc_ = BGRA8888ToARGB;
698 break;
699 }
700 case PixelFormat::ARGB_8888: {
701 pixelBytes_ = ARGB_8888_BYTES;
702 colorProc_ = ARGB8888ToARGB;
703 break;
704 }
705 case PixelFormat::ALPHA_8: {
706 pixelBytes_ = ALPHA_8_BYTES;
707 colorProc_ = ALPHA8ToARGB;
708 break;
709 }
710 case PixelFormat::RGB_565: {
711 pixelBytes_ = RGB_565_BYTES;
712 colorProc_ = RGB565ToARGB;
713 break;
714 }
715 case PixelFormat::RGB_888: {
716 pixelBytes_ = RGB_888_BYTES;
717 colorProc_ = RGB888ToARGB;
718 break;
719 }
720 case PixelFormat::NV12:
721 case PixelFormat::NV21: {
722 pixelBytes_ = YUV420_BYTES;
723 break;
724 }
725 case PixelFormat::CMYK:
726 pixelBytes_ = ARGB_8888_BYTES;
727 break;
728 case PixelFormat::RGBA_F16:
729 pixelBytes_ = BGRA_F16_BYTES;
730 break;
731 case PixelFormat::ASTC_4x4:
732 case PixelFormat::ASTC_6x6:
733 case PixelFormat::ASTC_8x8:
734 pixelBytes_ = ASTC_4x4_BYTES;
735 break;
736 default: {
737 IMAGE_LOGE("pixel format:[%{public}d] not supported.", format);
738 return false;
739 }
740 }
741 return true;
742 }
743
SetRowStride(uint32_t stride)744 void PixelMap::SetRowStride(uint32_t stride)
745 {
746 rowStride_ = stride;
747 }
748
UpdateImageInfo()749 void PixelMap::UpdateImageInfo()
750 {
751 SetImageInfo(imageInfo_, true);
752 }
753
SetImageInfo(ImageInfo & info)754 uint32_t PixelMap::SetImageInfo(ImageInfo &info)
755 {
756 return SetImageInfo(info, false);
757 }
758
SetRowDataSizeForImageInfo(ImageInfo info)759 uint32_t PixelMap::SetRowDataSizeForImageInfo(ImageInfo info)
760 {
761 if (info.pixelFormat == PixelFormat::ALPHA_8) {
762 rowDataSize_ = pixelBytes_ * ((info.size.width + FILL_NUMBER) / ALIGN_NUMBER * ALIGN_NUMBER);
763 SetRowStride(rowDataSize_);
764 IMAGE_LOGI("ALPHA_8 rowDataSize_ %{public}d.", rowDataSize_);
765 } else if (info.pixelFormat == PixelFormat::ASTC_4x4) {
766 rowDataSize_ = pixelBytes_ * (((info.size.width + NUM_3) >> NUM_2) << NUM_2);
767 } else if (info.pixelFormat == PixelFormat::ASTC_6x6) {
768 rowDataSize_ = pixelBytes_ * (((info.size.width + NUM_5) / NUM_6) * NUM_6);
769 } else if (info.pixelFormat == PixelFormat::ASTC_8x8) {
770 rowDataSize_ = pixelBytes_ * (((info.size.width + NUM_7) >> NUM_3) << NUM_3);
771 } else {
772 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
773 if (allocatorType_ == AllocatorType::DMA_ALLOC) {
774 if (context_ == nullptr) {
775 IMAGE_LOGE("set imageInfo failed, context_ is null");
776 return ERR_IMAGE_DATA_ABNORMAL;
777 }
778 SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(context_);
779 SetRowStride(sbBuffer->GetStride());
780 } else {
781 SetRowStride(pixelBytes_ * info.size.width);
782 }
783 #else
784 SetRowStride(pixelBytes_ * info.size.width);
785 #endif
786 rowDataSize_ = pixelBytes_ * info.size.width;
787 }
788 return SUCCESS;
789 }
790
SetImageInfo(ImageInfo & info,bool isReused)791 uint32_t PixelMap::SetImageInfo(ImageInfo &info, bool isReused)
792 {
793 if (info.size.width <= 0 || info.size.height <= 0) {
794 IMAGE_LOGE("pixel map image info invalid.");
795 return ERR_IMAGE_DATA_ABNORMAL;
796 }
797 if (!GetPixelFormatDetail(info.pixelFormat)) {
798 return ERR_IMAGE_DATA_UNSUPPORT;
799 }
800
801 if (pixelBytes_ <= 0) {
802 ResetPixelMap();
803 IMAGE_LOGE("pixel map bytes is invalid.");
804 return ERR_IMAGE_DATA_ABNORMAL;
805 }
806
807 if (allocatorType_ == AllocatorType::HEAP_ALLOC &&
808 ((static_cast<uint64_t>(pixelBytes_) * info.size.width) > PIXEL_MAP_MAX_RAM_SIZE)) {
809 ResetPixelMap();
810 IMAGE_LOGE("image size is out of range.");
811 return ERR_IMAGE_TOO_LARGE;
812 }
813
814 if (SetRowDataSizeForImageInfo(info) != SUCCESS) {
815 IMAGE_LOGE("pixel map set rowDataSize error.");
816 return ERR_IMAGE_DATA_ABNORMAL;
817 }
818
819 if (rowDataSize_ != 0 && allocatorType_ == AllocatorType::HEAP_ALLOC &&
820 info.size.height > (PIXEL_MAP_MAX_RAM_SIZE / rowDataSize_)) {
821 ResetPixelMap();
822 IMAGE_LOGE("pixel map byte count out of range.");
823 return ERR_IMAGE_TOO_LARGE;
824 }
825 if (!isReused) {
826 FreePixelMap();
827 }
828 imageInfo_ = info;
829 return SUCCESS;
830 }
831
GetPixel8(int32_t x,int32_t y)832 const uint8_t *PixelMap::GetPixel8(int32_t x, int32_t y)
833 {
834 if (!CheckValidParam(x, y) || (pixelBytes_ != ALPHA_8_BYTES)) {
835 IMAGE_LOGE("get addr8 pixel position:(%{public}d, %{public}d) pixel bytes:%{public}d invalid.", x, y,
836 pixelBytes_);
837 return nullptr;
838 }
839 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
840 return (data_ + y * rowStride_ + x);
841 #else
842 return (data_ + y * rowDataSize_ + x);
843 #endif
844 }
845
GetPixel16(int32_t x,int32_t y)846 const uint16_t *PixelMap::GetPixel16(int32_t x, int32_t y)
847 {
848 if (!CheckValidParam(x, y) || (pixelBytes_ != RGB_565_BYTES)) {
849 IMAGE_LOGE("get addr16 pixel position:(%{public}d, %{public}d) pixel bytes:%{public}d invalid.", x, y,
850 pixelBytes_);
851 return nullptr;
852 }
853 // convert uint8_t* to uint16_t*
854 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
855 return reinterpret_cast<uint16_t *>(data_ + y * rowStride_ + (static_cast<uint32_t>(x) << RGB_565_SHIFT));
856 #else
857 return reinterpret_cast<uint16_t *>(data_ + y * rowDataSize_ + (static_cast<uint32_t>(x) << RGB_565_SHIFT));
858 #endif
859 }
860
GetPixel32(int32_t x,int32_t y)861 const uint32_t *PixelMap::GetPixel32(int32_t x, int32_t y)
862 {
863 if (!CheckValidParam(x, y) || (pixelBytes_ != ARGB_8888_BYTES)) {
864 IMAGE_LOGE("get addr32 pixel position:(%{public}d, %{public}d) pixel bytes:%{public}d invalid.", x, y,
865 pixelBytes_);
866 return nullptr;
867 }
868 // convert uint8_t* to uint32_t*
869 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
870 return reinterpret_cast<uint32_t *>(data_ + y * rowStride_ + (static_cast<uint32_t>(x) << ARGB_8888_SHIFT));
871 #else
872 return reinterpret_cast<uint32_t *>(data_ + y * rowDataSize_ + (static_cast<uint32_t>(x) << ARGB_8888_SHIFT));
873 #endif
874 }
875
GetPixel(int32_t x,int32_t y)876 const uint8_t *PixelMap::GetPixel(int32_t x, int32_t y)
877 {
878 if (!CheckValidParam(x, y)) {
879 IMAGE_LOGE("input pixel position:(%{public}d, %{public}d) invalid.", x, y);
880 return nullptr;
881 }
882 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
883 return (data_ + y * rowStride_ + (static_cast<uint32_t>(x) * pixelBytes_));
884 #else
885 return (data_ + y * rowDataSize_ + (static_cast<uint32_t>(x) * pixelBytes_));
886 #endif
887 }
888
GetARGB32Color(int32_t x,int32_t y,uint32_t & color)889 bool PixelMap::GetARGB32Color(int32_t x, int32_t y, uint32_t &color)
890 {
891 if (colorProc_ == nullptr) {
892 IMAGE_LOGE("pixel format not supported.");
893 return false;
894 }
895 const uint8_t *src = GetPixel(x, y);
896 if (src == nullptr) {
897 IMAGE_LOGE("get pixel color error.");
898 return false;
899 }
900 // use founction point for frequently called interface
901 return colorProc_(src, ONE_PIXEL_SIZE * pixelBytes_, &color, ONE_PIXEL_SIZE);
902 }
903
ALPHA8ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)904 bool PixelMap::ALPHA8ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
905 {
906 if (inCount != outCount) {
907 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
908 return false;
909 }
910 const uint8_t *src = in;
911 for (uint32_t i = 0; i < outCount; i++) {
912 *out++ = GetColorARGB(*src++, BYTE_ZERO, BYTE_ZERO, BYTE_ZERO);
913 }
914 return true;
915 }
916
RGB565ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)917 bool PixelMap::RGB565ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
918 {
919 if (((inCount / RGB_565_BYTES) != outCount) && ((inCount % RGB_565_BYTES) != 0)) {
920 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
921 return false;
922 }
923 const uint16_t *src = reinterpret_cast<const uint16_t *>(in);
924 for (uint32_t i = 0; i < outCount; i++) {
925 uint16_t color = *src++;
926 *out++ = GetColorARGB(BYTE_FULL, RGB565ToR32(color), RGB565ToG32(color), RGB565ToB32(color));
927 }
928 return true;
929 }
930
ARGB8888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)931 bool PixelMap::ARGB8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
932 {
933 if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {
934 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
935 return false;
936 }
937 const uint32_t *src = reinterpret_cast<const uint32_t *>(in);
938 for (uint32_t i = 0; i < outCount; i++) {
939 uint32_t color = *src++;
940 *out++ = GetColorARGB(GetColorComp(color, ARGB32_A_SHIFT), GetColorComp(color, ARGB32_R_SHIFT),
941 GetColorComp(color, ARGB32_G_SHIFT), GetColorComp(color, ARGB32_B_SHIFT));
942 }
943 return true;
944 }
945
RGBA8888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)946 bool PixelMap::RGBA8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
947 {
948 if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {
949 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
950 return false;
951 }
952 const uint32_t *src = reinterpret_cast<const uint32_t *>(in);
953 for (uint32_t i = 0; i < outCount; i++) {
954 uint32_t color = *src++;
955 *out++ = GetColorARGB(GetColorComp(color, RGBA32_A_SHIFT), GetColorComp(color, RGBA32_R_SHIFT),
956 GetColorComp(color, RGBA32_G_SHIFT), GetColorComp(color, RGBA32_B_SHIFT));
957 }
958 return true;
959 }
960
BGRA8888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)961 bool PixelMap::BGRA8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
962 {
963 if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {
964 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
965 return false;
966 }
967 const uint32_t *src = reinterpret_cast<const uint32_t *>(in);
968 for (uint32_t i = 0; i < outCount; i++) {
969 uint32_t color = *src++;
970 *out++ = GetColorARGB(GetColorComp(color, BGRA32_A_SHIFT), GetColorComp(color, BGRA32_R_SHIFT),
971 GetColorComp(color, BGRA32_G_SHIFT), GetColorComp(color, BGRA32_B_SHIFT));
972 }
973 return true;
974 }
975
RGB888ToARGB(const uint8_t * in,uint32_t inCount,uint32_t * out,uint32_t outCount)976 bool PixelMap::RGB888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount)
977 {
978 if (((inCount / RGB_888_BYTES) != outCount) && ((inCount % RGB_888_BYTES) != 0)) {
979 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
980 return false;
981 }
982 const uint8_t *src = in;
983 for (uint32_t i = 0; i < outCount; i++) {
984 uint8_t colorR = *src++;
985 uint8_t colorG = *src++;
986 uint8_t colorB = *src++;
987 *out++ = GetColorARGB(BYTE_FULL, colorR, colorG, colorB);
988 }
989 return true;
990 }
991
GetPixelBytes()992 int32_t PixelMap::GetPixelBytes()
993 {
994 return pixelBytes_;
995 }
996
GetRowBytes()997 int32_t PixelMap::GetRowBytes()
998 {
999 return rowDataSize_;
1000 }
1001
GetByteCount()1002 int32_t PixelMap::GetByteCount()
1003 {
1004 IMAGE_LOGD("GetByteCount");
1005 return rowDataSize_ * imageInfo_.size.height;
1006 }
1007
GetWidth()1008 int32_t PixelMap::GetWidth()
1009 {
1010 return imageInfo_.size.width;
1011 }
1012
GetHeight()1013 int32_t PixelMap::GetHeight()
1014 {
1015 return imageInfo_.size.height;
1016 }
1017
GetTransformData(TransformData & transformData)1018 void PixelMap::GetTransformData(TransformData &transformData)
1019 {
1020 transformData = transformData_;
1021 }
1022
SetTransformData(TransformData transformData)1023 void PixelMap::SetTransformData(TransformData transformData)
1024 {
1025 transformData_ = transformData;
1026 }
1027
GetBaseDensity()1028 int32_t PixelMap::GetBaseDensity()
1029 {
1030 return imageInfo_.baseDensity;
1031 }
1032
GetImageInfo(ImageInfo & imageInfo)1033 void PixelMap::GetImageInfo(ImageInfo &imageInfo)
1034 {
1035 imageInfo = imageInfo_;
1036 }
1037
GetPixelFormat()1038 PixelFormat PixelMap::GetPixelFormat()
1039 {
1040 return imageInfo_.pixelFormat;
1041 }
1042
GetColorSpace()1043 ColorSpace PixelMap::GetColorSpace()
1044 {
1045 return imageInfo_.colorSpace;
1046 }
1047
GetAlphaType()1048 AlphaType PixelMap::GetAlphaType()
1049 {
1050 return imageInfo_.alphaType;
1051 }
1052
GetPixels()1053 const uint8_t *PixelMap::GetPixels()
1054 {
1055 return data_;
1056 }
1057
GetARGB32ColorA(uint32_t color)1058 uint8_t PixelMap::GetARGB32ColorA(uint32_t color)
1059 {
1060 return (color >> ARGB_A_SHIFT) & ARGB_MASK;
1061 }
1062
GetARGB32ColorR(uint32_t color)1063 uint8_t PixelMap::GetARGB32ColorR(uint32_t color)
1064 {
1065 return (color >> ARGB_R_SHIFT) & ARGB_MASK;
1066 }
1067
GetARGB32ColorG(uint32_t color)1068 uint8_t PixelMap::GetARGB32ColorG(uint32_t color)
1069 {
1070 return (color >> ARGB_G_SHIFT) & ARGB_MASK;
1071 }
1072
GetARGB32ColorB(uint32_t color)1073 uint8_t PixelMap::GetARGB32ColorB(uint32_t color)
1074 {
1075 return (color >> ARGB_B_SHIFT) & ARGB_MASK;
1076 }
1077
IsSameImage(const PixelMap & other)1078 bool PixelMap::IsSameImage(const PixelMap &other)
1079 {
1080 if (data_ == nullptr || other.data_ == nullptr) {
1081 IMAGE_LOGE("IsSameImage data_ is nullptr.");
1082 return false;
1083 }
1084 if (imageInfo_.size.width != other.imageInfo_.size.width ||
1085 imageInfo_.size.height != other.imageInfo_.size.height ||
1086 imageInfo_.pixelFormat != other.imageInfo_.pixelFormat || imageInfo_.alphaType != other.imageInfo_.alphaType) {
1087 IMAGE_LOGI("IsSameImage imageInfo is not same");
1088 return false;
1089 }
1090 uint64_t size = static_cast<uint64_t>(rowDataSize_) * imageInfo_.size.height;
1091 if (memcmp(data_, other.data_, size) != 0) {
1092 IMAGE_LOGI("IsSameImage memcmp is not same");
1093 return false;
1094 }
1095 return true;
1096 }
1097
ReadPixels(const uint64_t & bufferSize,uint8_t * dst)1098 uint32_t PixelMap::ReadPixels(const uint64_t &bufferSize, uint8_t *dst)
1099 {
1100 ImageTrace imageTrace("ReadPixels by bufferSize");
1101 if (dst == nullptr) {
1102 IMAGE_LOGE("read pixels by buffer input dst address is null.");
1103 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1104 }
1105 if (data_ == nullptr) {
1106 IMAGE_LOGE("read pixels by buffer current PixelMap data is null.");
1107 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1108 }
1109 if (bufferSize < static_cast<uint64_t>(pixelsSize_)) {
1110 IMAGE_LOGE("read pixels by buffer input dst buffer(%{public}llu) < current pixelmap size(%{public}u).",
1111 static_cast<unsigned long long>(bufferSize), pixelsSize_);
1112 return ERR_IMAGE_INVALID_PARAMETER;
1113 }
1114
1115 // Copy the actual pixel data without padding bytes
1116 for (int i = 0; i < imageInfo_.size.height; ++i) {
1117 errno_t ret = memcpy_s(dst, rowDataSize_, data_ + i * rowStride_, rowDataSize_);
1118 if (ret != 0) {
1119 IMAGE_LOGE("read pixels by buffer memcpy the pixelmap data to dst fail, error:%{public}d", ret);
1120 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1121 }
1122 dst += rowDataSize_; // Move the destination buffer pointer to the next row
1123 }
1124 return SUCCESS;
1125 }
1126
CheckPixelsInput(const uint8_t * dst,const uint64_t & bufferSize,const uint32_t & offset,const uint32_t & stride,const Rect & region)1127 bool PixelMap::CheckPixelsInput(const uint8_t *dst, const uint64_t &bufferSize, const uint32_t &offset,
1128 const uint32_t &stride, const Rect ®ion)
1129 {
1130 if (dst == nullptr) {
1131 IMAGE_LOGE("CheckPixelsInput input dst address is null.");
1132 return false;
1133 }
1134
1135 if (bufferSize == 0) {
1136 IMAGE_LOGE("CheckPixelsInput input buffer size is 0.");
1137 return false;
1138 }
1139
1140 if (region.left < 0 || region.top < 0 || stride > numeric_limits<int32_t>::max() ||
1141 static_cast<uint64_t>(offset) > bufferSize) {
1142 IMAGE_LOGE(
1143 "CheckPixelsInput left(%{public}d) or top(%{public}d) or stride(%{public}u) or offset(%{public}u) < 0.",
1144 region.left, region.top, stride, offset);
1145 return false;
1146 }
1147 if (region.width <= 0 || region.height <= 0 || region.width > MAX_DIMENSION || region.height > MAX_DIMENSION) {
1148 IMAGE_LOGE("CheckPixelsInput width(%{public}d) or height(%{public}d) is < 0.", region.width, region.height);
1149 return false;
1150 }
1151 if (region.left > GetWidth() - region.width) {
1152 IMAGE_LOGE("CheckPixelsInput left(%{public}d) + width(%{public}d) is > pixelmap width(%{public}d).",
1153 region.left, region.width, GetWidth());
1154 return false;
1155 }
1156 if (region.top > GetHeight() - region.height) {
1157 IMAGE_LOGE("CheckPixelsInput top(%{public}d) + height(%{public}d) is > pixelmap height(%{public}d).",
1158 region.top, region.height, GetHeight());
1159 return false;
1160 }
1161 uint32_t regionStride = static_cast<uint32_t>(region.width) * 4; // bytes count, need multiply by 4
1162 if (stride < regionStride) {
1163 IMAGE_LOGE("CheckPixelsInput stride(%{public}d) < width*4 (%{public}d).", stride, regionStride);
1164 return false;
1165 }
1166
1167 if (bufferSize < regionStride) {
1168 IMAGE_LOGE("CheckPixelsInput input buffer size is < width * 4.");
1169 return false;
1170 }
1171 uint64_t lastLinePos = offset + static_cast<uint64_t>(region.height - 1) * stride; // "1" is except the last line.
1172 if (static_cast<uint64_t>(offset) > (bufferSize - regionStride) || lastLinePos > (bufferSize - regionStride)) {
1173 IMAGE_LOGE(
1174 "CheckPixelsInput fail, height(%{public}d), width(%{public}d), lastLine(%{public}llu), "
1175 "offset(%{public}u), bufferSize:%{public}llu.", region.height, region.width,
1176 static_cast<unsigned long long>(lastLinePos), offset, static_cast<unsigned long long>(bufferSize));
1177 return false;
1178 }
1179 return true;
1180 }
1181
ReadPixels(const uint64_t & bufferSize,const uint32_t & offset,const uint32_t & stride,const Rect & region,uint8_t * dst)1182 uint32_t PixelMap::ReadPixels(const uint64_t &bufferSize, const uint32_t &offset, const uint32_t &stride,
1183 const Rect ®ion, uint8_t *dst)
1184 {
1185 if (!CheckPixelsInput(dst, bufferSize, offset, stride, region)) {
1186 IMAGE_LOGE("read pixels by rect input parameter fail.");
1187 return ERR_IMAGE_INVALID_PARAMETER;
1188 }
1189 if (data_ == nullptr) {
1190 IMAGE_LOGE("read pixels by rect this pixel data is null.");
1191 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1192 }
1193 ImageInfo dstImageInfo =
1194 MakeImageInfo(region.width, region.height, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1195 Position srcPosition { region.left, region.top };
1196 if (!PixelConvertAdapter::ReadPixelsConvert(data_, srcPosition, rowStride_, imageInfo_, dst + offset, stride,
1197 dstImageInfo)) {
1198 IMAGE_LOGE("read pixels by rect call ReadPixelsConvert fail.");
1199 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1200 }
1201 return SUCCESS;
1202 }
1203
ReadPixel(const Position & pos,uint32_t & dst)1204 uint32_t PixelMap::ReadPixel(const Position &pos, uint32_t &dst)
1205 {
1206 if (pos.x < 0 || pos.y < 0 || pos.x >= GetWidth() || pos.y >= GetHeight()) {
1207 IMAGE_LOGE("read pixel by pos input invalid exception. [x(%{public}d), y(%{public}d)]", pos.x, pos.y);
1208 return ERR_IMAGE_INVALID_PARAMETER;
1209 }
1210 if (data_ == nullptr) {
1211 IMAGE_LOGE("read pixel by pos source data is null.");
1212 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1213 }
1214 ImageInfo dstImageInfo =
1215 MakeImageInfo(PER_PIXEL_LEN, PER_PIXEL_LEN, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1216 uint32_t dstRowBytes = BGRA_BYTES;
1217 Position srcPosition { pos.x, pos.y };
1218 if (!PixelConvertAdapter::ReadPixelsConvert(data_, srcPosition, rowStride_, imageInfo_, &dst, dstRowBytes,
1219 dstImageInfo)) {
1220 IMAGE_LOGE("read pixel by pos call ReadPixelsConvert fail.");
1221 return ERR_IMAGE_READ_PIXELMAP_FAILED;
1222 }
1223 return SUCCESS;
1224 }
1225
ResetConfig(const Size & size,const PixelFormat & format)1226 uint32_t PixelMap::ResetConfig(const Size &size, const PixelFormat &format)
1227 {
1228 if (size.width <= 0 || size.height <= 0) {
1229 IMAGE_LOGE("ResetConfig reset input width(%{public}d) or height(%{public}d) is < 0.", size.width,
1230 size.height);
1231 return ERR_IMAGE_INVALID_PARAMETER;
1232 }
1233 uint32_t bytesPerPixel = ImageUtils::GetPixelBytes(format);
1234 if (bytesPerPixel == 0) {
1235 IMAGE_LOGE("ResetConfig get bytes by per pixel fail.");
1236 return ERR_IMAGE_INVALID_PARAMETER;
1237 }
1238 uint64_t dstSize = static_cast<uint64_t>(size.width) * size.height * bytesPerPixel;
1239 if (dstSize > static_cast<uint64_t>(pixelsSize_)) {
1240 IMAGE_LOGE("ResetConfig reset dstSize(%{public}llu) > current(%{public}u).",
1241 static_cast<unsigned long long>(dstSize), pixelsSize_);
1242 return ERR_IMAGE_INVALID_PARAMETER;
1243 }
1244 AlphaType dstAlphaType = ImageUtils::GetValidAlphaTypeByFormat(GetAlphaType(), format);
1245 if (dstAlphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
1246 IMAGE_LOGE("ResetConfig Failed to get validate alpha type.");
1247 return ERR_IMAGE_INVALID_PARAMETER;
1248 }
1249 ImageInfo dstInfo = MakeImageInfo(size.width, size.height, format, dstAlphaType);
1250 uint32_t ret = SetImageInfo(dstInfo, true);
1251 if (ret != SUCCESS) {
1252 IMAGE_LOGE("ResetConfig call SetImageInfo Failed. ret:%{public}u", ret);
1253 return ERR_IMAGE_CONFIG_FAILED;
1254 }
1255 return SUCCESS;
1256 }
1257
SetAlphaType(const AlphaType & alphaType)1258 bool PixelMap::SetAlphaType(const AlphaType &alphaType)
1259 {
1260 AlphaType type = ImageUtils::GetValidAlphaTypeByFormat(alphaType, imageInfo_.pixelFormat);
1261 if (type == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
1262 IMAGE_LOGE("SetAlphaType Failed to get validate alpha type.");
1263 return false;
1264 }
1265 ImageInfo dstInfo = imageInfo_;
1266 dstInfo.alphaType = type;
1267 uint32_t ret = SetImageInfo(dstInfo, true);
1268 if (ret != SUCCESS) {
1269 IMAGE_LOGE("SetAlphaType call SetImageInfo Failed. ret:%{public}u", ret);
1270 return false;
1271 }
1272 return true;
1273 }
1274
WritePixel(const Position & pos,const uint32_t & color)1275 uint32_t PixelMap::WritePixel(const Position &pos, const uint32_t &color)
1276 {
1277 if (pos.x < 0 || pos.y < 0 || pos.x >= GetWidth() || pos.y >= GetHeight()) {
1278 IMAGE_LOGE(
1279 "write pixel by pos but input position is invalid. [x(%{public}d), y(%{public}d)]"\
1280 "Width() %{public}d, Height() %{public}d, ", pos.x, pos.y, GetWidth(), GetHeight());
1281 return ERR_IMAGE_INVALID_PARAMETER;
1282 }
1283 if (!IsEditable()) {
1284 IMAGE_LOGE("write pixel by pos pixelmap is not editable.");
1285 return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
1286 }
1287 if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1288 IMAGE_LOGE("write pixel by pos current pixelmap image info is invalid.");
1289 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1290 }
1291 if (data_ == nullptr) {
1292 IMAGE_LOGE("write pixel by pos but current pixelmap data is nullptr.");
1293 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1294 }
1295 ImageInfo srcImageInfo =
1296 MakeImageInfo(PER_PIXEL_LEN, PER_PIXEL_LEN, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1297 uint32_t srcRowBytes = BGRA_BYTES;
1298 Position dstPosition { pos.x, pos.y }; // source is per pixel.
1299 if (!PixelConvertAdapter::WritePixelsConvert(&color, srcRowBytes, srcImageInfo, data_, dstPosition, rowStride_,
1300 imageInfo_)) {
1301 IMAGE_LOGE("write pixel by pos call WritePixelsConvert fail.");
1302 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1303 }
1304 return SUCCESS;
1305 }
1306
WritePixels(const uint8_t * source,const uint64_t & bufferSize,const uint32_t & offset,const uint32_t & stride,const Rect & region)1307 uint32_t PixelMap::WritePixels(const uint8_t *source, const uint64_t &bufferSize, const uint32_t &offset,
1308 const uint32_t &stride, const Rect ®ion)
1309 {
1310 if (!CheckPixelsInput(source, bufferSize, offset, stride, region)) {
1311 IMAGE_LOGE("write pixel by rect input parameter fail.");
1312 return ERR_IMAGE_INVALID_PARAMETER;
1313 }
1314 if (!IsEditable()) {
1315 IMAGE_LOGE("write pixel by rect pixelmap data is not editable.");
1316 return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
1317 }
1318 if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1319 IMAGE_LOGE("write pixel by rect current pixelmap image info is invalid.");
1320 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1321 }
1322 if (data_ == nullptr) {
1323 IMAGE_LOGE("write pixel by rect current pixel map data is null.");
1324 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1325 }
1326 uint32_t bytesPerPixel = ImageUtils::GetPixelBytes(imageInfo_.pixelFormat);
1327 if (bytesPerPixel == 0) {
1328 IMAGE_LOGE("write pixel by rect get bytes by per pixel fail.");
1329 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1330 }
1331 Position dstPosition { region.left, region.top };
1332 ImageInfo srcInfo =
1333 MakeImageInfo(region.width, region.height, PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1334 if (!PixelConvertAdapter::WritePixelsConvert(source + offset, stride, srcInfo, data_, dstPosition, rowStride_,
1335 imageInfo_)) {
1336 IMAGE_LOGE("write pixel by rect call WritePixelsConvert fail.");
1337 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1338 }
1339 return SUCCESS;
1340 }
1341
WritePixels(const uint8_t * source,const uint64_t & bufferSize)1342 uint32_t PixelMap::WritePixels(const uint8_t *source, const uint64_t &bufferSize)
1343 {
1344 ImageTrace imageTrace("WritePixels");
1345 if (source == nullptr || bufferSize < static_cast<uint64_t>(pixelsSize_)) {
1346 IMAGE_LOGE("write pixels by buffer source is nullptr or size(%{public}llu) < pixelSize(%{public}u).",
1347 static_cast<unsigned long long>(bufferSize), pixelsSize_);
1348 return ERR_IMAGE_INVALID_PARAMETER;
1349 }
1350 if (!IsEditable()) {
1351 IMAGE_LOGE("write pixels by buffer pixelmap data is not editable.");
1352 return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
1353 }
1354 if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1355 IMAGE_LOGE("write pixels by buffer current pixelmap image info is invalid.");
1356 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1357 }
1358 if (data_ == nullptr) {
1359 IMAGE_LOGE("write pixels by buffer current pixelmap data is nullptr.");
1360 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1361 }
1362
1363 for (int i = 0; i < imageInfo_.size.height; ++i) {
1364 const uint8_t* sourceRow = source + i * rowDataSize_;
1365 errno_t ret = memcpy_s(data_ + i * rowStride_, rowDataSize_, sourceRow, rowDataSize_);
1366 if (ret != 0) {
1367 IMAGE_LOGE("write pixels by buffer memcpy the pixelmap data to dst fail, error:%{public}d", ret);
1368 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
1369 }
1370 }
1371 return SUCCESS;
1372 }
1373
WritePixels(const uint32_t & color)1374 bool PixelMap::WritePixels(const uint32_t &color)
1375 {
1376 if (!IsEditable()) {
1377 IMAGE_LOGE("erase pixels by color pixelmap data is not editable.");
1378 return false;
1379 }
1380 if (!ImageUtils::IsValidImageInfo(imageInfo_)) {
1381 IMAGE_LOGE("erase pixels by color current pixelmap image info is invalid.");
1382 return false;
1383 }
1384 if (data_ == nullptr) {
1385 IMAGE_LOGE("erase pixels by color current pixel map data is null.");
1386 return false;
1387 }
1388 ImageInfo srcInfo =
1389 MakeImageInfo(imageInfo_.size.width, imageInfo_.size.height, imageInfo_.pixelFormat, imageInfo_.alphaType);
1390 if (!PixelConvertAdapter::EraseBitmap(data_, rowStride_, srcInfo, color)) {
1391 IMAGE_LOGE("erase pixels by color call EraseBitmap fail.");
1392 return false;
1393 }
1394 return true;
1395 }
1396
IsStrideAlignment()1397 bool PixelMap::IsStrideAlignment()
1398 {
1399 IMAGE_LOGE("IsStrideAlignment error ");
1400 if (allocatorType_ == AllocatorType::DMA_ALLOC) {
1401 IMAGE_LOGE("SetPixelsAddr error allocatorType_ %{public}d ", allocatorType_);
1402 return true;
1403 }
1404 IMAGE_LOGE("IsStrideAlignment error ");
1405 return false;
1406 }
1407
GetAllocatorType()1408 AllocatorType PixelMap::GetAllocatorType()
1409 {
1410 return allocatorType_;
1411 }
1412
GetFd() const1413 void *PixelMap::GetFd() const
1414 {
1415 return context_;
1416 }
1417
ReleaseMemory(AllocatorType allocType,void * addr,void * context,uint32_t size)1418 void PixelMap::ReleaseMemory(AllocatorType allocType, void *addr, void *context, uint32_t size)
1419 {
1420 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1421 if (allocType == AllocatorType::SHARE_MEM_ALLOC) {
1422 if (context != nullptr) {
1423 int *fd = static_cast<int *>(context);
1424 if (addr != nullptr) {
1425 ::munmap(addr, size);
1426 }
1427 if (fd != nullptr) {
1428 ::close(*fd);
1429 }
1430 context = nullptr;
1431 addr = nullptr;
1432 }
1433 } else if (allocType == AllocatorType::HEAP_ALLOC) {
1434 if (addr != nullptr) {
1435 free(addr);
1436 addr = nullptr;
1437 }
1438 } else if (allocType == AllocatorType::DMA_ALLOC) {
1439 if (context != nullptr) {
1440 ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer*>(context));
1441 }
1442 context = nullptr;
1443 addr = nullptr;
1444 }
1445 #else
1446 if (addr != nullptr) {
1447 free(addr);
1448 addr = nullptr;
1449 }
1450 #endif
1451 }
1452
WriteAshmemDataToParcel(Parcel & parcel,size_t size) const1453 bool PixelMap::WriteAshmemDataToParcel(Parcel &parcel, size_t size) const
1454 {
1455 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1456 const uint8_t *data = data_;
1457 uint32_t id = GetUniqueId();
1458 std::string name = "Parcel ImageData, uniqueId: " + std::to_string(getpid()) + '_' + std::to_string(id);
1459 int fd = AshmemCreate(name.c_str(), size);
1460 IMAGE_LOGI("AshmemCreate:[%{public}d].", fd);
1461 if (fd < 0) {
1462 return false;
1463 }
1464
1465 int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
1466 IMAGE_LOGI("AshmemSetProt:[%{public}d].", result);
1467 if (result < 0) {
1468 ::close(fd);
1469 return false;
1470 }
1471 void *ptr = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1472 if (ptr == MAP_FAILED) {
1473 ::close(fd);
1474 IMAGE_LOGE("WriteAshmemData map failed, errno:%{public}d", errno);
1475 return false;
1476 }
1477 IMAGE_LOGI("mmap success");
1478
1479 if (memcpy_s(ptr, size, data, size) != EOK) {
1480 ::munmap(ptr, size);
1481 ::close(fd);
1482 IMAGE_LOGE("WriteAshmemData memcpy_s error");
1483 return false;
1484 }
1485
1486 if (!WriteFileDescriptor(parcel, fd)) {
1487 ::munmap(ptr, size);
1488 ::close(fd);
1489 IMAGE_LOGE("WriteAshmemData WriteFileDescriptor error");
1490 return false;
1491 }
1492 IMAGE_LOGD("WriteAshmemData WriteFileDescriptor success");
1493 ::munmap(ptr, size);
1494 ::close(fd);
1495 return true;
1496 #endif
1497 IMAGE_LOGE("WriteAshmemData not support crossplatform");
1498 return false;
1499 }
1500
WriteImageData(Parcel & parcel,size_t size) const1501 bool PixelMap::WriteImageData(Parcel &parcel, size_t size) const
1502 {
1503 const uint8_t *data = data_;
1504 if (data == nullptr || size > MAX_IMAGEDATA_SIZE) {
1505 IMAGE_LOGE("WriteImageData failed, data is null or size bigger than 128M.");
1506 return false;
1507 }
1508
1509 if (!parcel.WriteInt32(size)) {
1510 IMAGE_LOGE("WriteImageData size failed.");
1511 return false;
1512 }
1513 if (size <= MIN_IMAGEDATA_SIZE) {
1514 return parcel.WriteUnpadBuffer(data, size);
1515 }
1516 return WriteAshmemDataToParcel(parcel, size);
1517 }
1518
ReadHeapDataFromParcel(Parcel & parcel,int32_t bufferSize)1519 uint8_t *PixelMap::ReadHeapDataFromParcel(Parcel &parcel, int32_t bufferSize)
1520 {
1521 uint8_t *base = nullptr;
1522 if (bufferSize <= 0) {
1523 IMAGE_LOGE("malloc parameter bufferSize:[%{public}d] error.", bufferSize);
1524 return nullptr;
1525 }
1526
1527 const uint8_t *ptr = parcel.ReadUnpadBuffer(bufferSize);
1528 if (ptr == nullptr) {
1529 IMAGE_LOGE("read buffer from parcel failed, read buffer addr is null");
1530 return nullptr;
1531 }
1532
1533 base = static_cast<uint8_t *>(malloc(bufferSize));
1534 if (base == nullptr) {
1535 IMAGE_LOGE("alloc output pixel memory size:[%{public}d] error.", bufferSize);
1536 return nullptr;
1537 }
1538 if (memcpy_s(base, bufferSize, ptr, bufferSize) != 0) {
1539 free(base);
1540 base = nullptr;
1541 IMAGE_LOGE("memcpy pixel data size:[%{public}d] error.", bufferSize);
1542 return nullptr;
1543 }
1544 return base;
1545 }
1546
ReadAshmemDataFromParcel(Parcel & parcel,int32_t bufferSize)1547 uint8_t *PixelMap::ReadAshmemDataFromParcel(Parcel &parcel, int32_t bufferSize)
1548 {
1549 uint8_t *base = nullptr;
1550 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1551 int fd = ReadFileDescriptor(parcel);
1552 if (fd < 0) {
1553 IMAGE_LOGE("read fd :[%{public}d] error", fd);
1554 return nullptr;
1555 }
1556 if (bufferSize <= 0 || bufferSize > PIXEL_MAP_MAX_RAM_SIZE) {
1557 IMAGE_LOGE("malloc parameter bufferSize:[%{public}d] error.", bufferSize);
1558 return nullptr;
1559 }
1560
1561 void *ptr = ::mmap(nullptr, bufferSize, PROT_READ, MAP_SHARED, fd, 0);
1562 if (ptr == MAP_FAILED) {
1563 // do not close fd here. fd will be closed in FileDescriptor, ::close(fd)
1564 IMAGE_LOGE("ReadImageData map failed, errno:%{public}d", errno);
1565 return nullptr;
1566 }
1567
1568 base = static_cast<uint8_t *>(malloc(bufferSize));
1569 if (base == nullptr) {
1570 ::munmap(ptr, bufferSize);
1571 IMAGE_LOGE("alloc output pixel memory size:[%{public}d] error.", bufferSize);
1572 return nullptr;
1573 }
1574 if (memcpy_s(base, bufferSize, ptr, bufferSize) != 0) {
1575 ::munmap(ptr, bufferSize);
1576 free(base);
1577 base = nullptr;
1578 IMAGE_LOGE("memcpy pixel data size:[%{public}d] error.", bufferSize);
1579 return nullptr;
1580 }
1581
1582 ReleaseMemory(AllocatorType::SHARE_MEM_ALLOC, ptr, &fd, bufferSize);
1583 #endif
1584 return base;
1585 }
1586
ReadImageData(Parcel & parcel,int32_t bufferSize)1587 uint8_t *PixelMap::ReadImageData(Parcel &parcel, int32_t bufferSize)
1588 {
1589 #if !defined(_WIN32) && !defined(_APPLE) &&!defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1590 if (static_cast<unsigned int>(bufferSize) <= MIN_IMAGEDATA_SIZE) {
1591 return ReadHeapDataFromParcel(parcel, bufferSize);
1592 } else {
1593 return ReadAshmemDataFromParcel(parcel, bufferSize);
1594 }
1595 #else
1596 return ReadHeapDataFromParcel(parcel, bufferSize);
1597 #endif
1598 }
1599
WriteFileDescriptor(Parcel & parcel,int fd)1600 bool PixelMap::WriteFileDescriptor(Parcel &parcel, int fd)
1601 {
1602 #if !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1603 if (fd < 0) {
1604 return false;
1605 }
1606 int dupFd = dup(fd);
1607 if (dupFd < 0) {
1608 return false;
1609 }
1610 sptr<IPCFileDescriptor> descriptor = new IPCFileDescriptor(dupFd);
1611 return parcel.WriteObject<IPCFileDescriptor>(descriptor);
1612 #else
1613 return false;
1614 #endif
1615 }
1616
ReadFileDescriptor(Parcel & parcel)1617 int PixelMap::ReadFileDescriptor(Parcel &parcel)
1618 {
1619 #if !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1620 sptr<IPCFileDescriptor> descriptor = parcel.ReadObject<IPCFileDescriptor>();
1621 if (descriptor == nullptr) {
1622 return -1;
1623 }
1624 int fd = descriptor->GetFd();
1625 if (fd < 0) {
1626 return -1;
1627 }
1628 return dup(fd);
1629 #else
1630 return -1;
1631 #endif
1632 }
1633
WriteImageInfo(Parcel & parcel) const1634 bool PixelMap::WriteImageInfo(Parcel &parcel) const
1635 {
1636 if (!parcel.WriteInt32(imageInfo_.size.width)) {
1637 IMAGE_LOGE("write image info width:[%{public}d] to parcel failed.", imageInfo_.size.width);
1638 return false;
1639 }
1640 if (!parcel.WriteInt32(imageInfo_.size.height)) {
1641 IMAGE_LOGE("write image info height:[%{public}d] to parcel failed.", imageInfo_.size.height);
1642 return false;
1643 }
1644 if (!parcel.WriteInt32(static_cast<int32_t>(imageInfo_.pixelFormat))) {
1645 IMAGE_LOGE("write image info pixel format:[%{public}d] to parcel failed.", imageInfo_.pixelFormat);
1646 return false;
1647 }
1648 if (!parcel.WriteInt32(static_cast<int32_t>(imageInfo_.colorSpace))) {
1649 IMAGE_LOGE("write image info color space:[%{public}d] to parcel failed.", imageInfo_.colorSpace);
1650 return false;
1651 }
1652 if (!parcel.WriteInt32(static_cast<int32_t>(imageInfo_.alphaType))) {
1653 IMAGE_LOGE("write image info alpha type:[%{public}d] to parcel failed.", imageInfo_.alphaType);
1654 return false;
1655 }
1656 if (!parcel.WriteInt32(imageInfo_.baseDensity)) {
1657 IMAGE_LOGE("write image info base density:[%{public}d] to parcel failed.", imageInfo_.baseDensity);
1658 return false;
1659 }
1660 return true;
1661 }
1662
WriteInfoToParcel(Parcel & parcel) const1663 bool PixelMap::WriteInfoToParcel(Parcel &parcel) const
1664 {
1665 if (!WriteImageInfo(parcel)) {
1666 IMAGE_LOGE("write image info to parcel failed.");
1667 return false;
1668 }
1669
1670 if (!parcel.WriteBool(editable_)) {
1671 IMAGE_LOGE("write pixel map editable to parcel failed.");
1672 return false;
1673 }
1674
1675 if (!parcel.WriteBool(isAstc_)) {
1676 IMAGE_LOGE("write pixel map isAstc_ to parcel failed.");
1677 return false;
1678 }
1679
1680 if (!parcel.WriteInt32(static_cast<int32_t>(allocatorType_))) {
1681 IMAGE_LOGE("write pixel map allocator type:[%{public}d] to parcel failed.", allocatorType_);
1682 return false;
1683 }
1684
1685 if (!parcel.WriteInt32(static_cast<int32_t>(grColorSpace_ ?
1686 grColorSpace_->GetColorSpaceName() : ERR_MEDIA_INVALID_VALUE))) {
1687 IMAGE_LOGE("write pixel map grColorSpace to parcel failed.");
1688 return false;
1689 }
1690 return true;
1691 }
1692
WriteTransformDataToParcel(Parcel & parcel) const1693 bool PixelMap::WriteTransformDataToParcel(Parcel &parcel) const
1694 {
1695 if (isAstc_) {
1696 if (!parcel.WriteFloat(static_cast<float>(transformData_.scaleX))) {
1697 IMAGE_LOGE("write scaleX:[%{public}f] to parcel failed.", transformData_.scaleX);
1698 return false;
1699 }
1700 if (!parcel.WriteFloat(static_cast<float>(transformData_.scaleY))) {
1701 IMAGE_LOGE("write scaleY:[%{public}f] to parcel failed.", transformData_.scaleY);
1702 return false;
1703 }
1704 if (!parcel.WriteFloat(static_cast<float>(transformData_.rotateD))) {
1705 IMAGE_LOGE("write rotateD:[%{public}f] to parcel failed.", transformData_.rotateD);
1706 return false;
1707 }
1708 if (!parcel.WriteFloat(static_cast<float>(transformData_.cropLeft))) {
1709 IMAGE_LOGE("write cropLeft:[%{public}f] to parcel failed.", transformData_.cropLeft);
1710 return false;
1711 }
1712 if (!parcel.WriteFloat(static_cast<float>(transformData_.cropTop))) {
1713 IMAGE_LOGE("write cropTop:[%{public}f] to parcel failed.", transformData_.cropTop);
1714 return false;
1715 }
1716 if (!parcel.WriteFloat(static_cast<float>(transformData_.cropWidth))) {
1717 IMAGE_LOGE("write cropWidth:[%{public}f] to parcel failed.", transformData_.cropWidth);
1718 return false;
1719 }
1720 if (!parcel.WriteFloat(static_cast<float>(transformData_.cropHeight))) {
1721 IMAGE_LOGE("write cropHeight:[%{public}f] to parcel failed.", transformData_.cropHeight);
1722 return false;
1723 }
1724 if (!parcel.WriteFloat(static_cast<float>(transformData_.translateX))) {
1725 IMAGE_LOGE("write translateX:[%{public}f] to parcel failed.", transformData_.translateX);
1726 return false;
1727 }
1728 if (!parcel.WriteFloat(static_cast<float>(transformData_.translateY))) {
1729 IMAGE_LOGE("write translateY:[%{public}f] to parcel failed.", transformData_.translateY);
1730 return false;
1731 }
1732 if (!parcel.WriteBool(static_cast<bool>(transformData_.flipX))) {
1733 IMAGE_LOGE("write astc transformData_.flipX to parcel failed.");
1734 return false;
1735 }
1736 if (!parcel.WriteBool(static_cast<bool>(transformData_.flipY))) {
1737 IMAGE_LOGE("write astc transformData_.flipY to parcel failed.");
1738 return false;
1739 }
1740 }
1741 return true;
1742 }
1743
WriteAstcRealSizeToParcel(Parcel & parcel) const1744 bool PixelMap::WriteAstcRealSizeToParcel(Parcel &parcel) const
1745 {
1746 if (isAstc_) {
1747 if (!parcel.WriteInt32(static_cast<int32_t>(astcrealSize_.width))) {
1748 IMAGE_LOGE("write astcrealSize_.width:[%{public}d] to parcel failed.", astcrealSize_.width);
1749 return false;
1750 }
1751 if (!parcel.WriteInt32(static_cast<int32_t>(astcrealSize_.height))) {
1752 IMAGE_LOGE("write astcrealSize_.height:[%{public}d] to parcel failed.", astcrealSize_.height);
1753 return false;
1754 }
1755 }
1756 return true;
1757 }
1758
Marshalling(Parcel & parcel) const1759 bool PixelMap::Marshalling(Parcel &parcel) const
1760 {
1761 int32_t PIXEL_MAP_INFO_MAX_LENGTH = 128;
1762 int32_t bufferSize = rowDataSize_ * imageInfo_.size.height;
1763 if (isAstc_) {
1764 bufferSize = pixelsSize_;
1765 }
1766 if (static_cast<size_t>(bufferSize) <= MIN_IMAGEDATA_SIZE &&
1767 static_cast<size_t>(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH) > parcel.GetDataCapacity() &&
1768 !parcel.SetDataCapacity(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH)) {
1769 IMAGE_LOGE("set parcel max capacity:[%{public}d] failed.", bufferSize + PIXEL_MAP_INFO_MAX_LENGTH);
1770 return false;
1771 }
1772 if (!WriteInfoToParcel(parcel)) {
1773 IMAGE_LOGE("write info to parcel failed.");
1774 return false;
1775 }
1776 if (!parcel.WriteInt32(static_cast<int32_t>(rowDataSize_))) {
1777 IMAGE_LOGE("write image info rowStride_:[%{public}d] to parcel failed.", rowDataSize_);
1778 return false;
1779 }
1780 #if !defined(_WIN32) && !defined(_APPLE) &&!defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1781 if (allocatorType_ == AllocatorType::SHARE_MEM_ALLOC) {
1782 if (!parcel.WriteInt32(bufferSize)) {
1783 return false;
1784 }
1785
1786 int *fd = static_cast<int *>(context_);
1787 if (fd == nullptr || *fd < 0) {
1788 IMAGE_LOGE("write pixel map failed, fd is [%{public}d] or fd < 0.", fd == nullptr ? 1 : 0);
1789 return false;
1790 }
1791
1792 if (!WriteFileDescriptor(parcel, *fd)) {
1793 IMAGE_LOGE("write pixel map fd:[%{public}d] to parcel failed.", *fd);
1794 return false;
1795 }
1796 } else if (allocatorType_ == AllocatorType::DMA_ALLOC) {
1797 if (!parcel.WriteInt32(bufferSize)) {
1798 return false;
1799 }
1800 SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*> (context_);
1801 sbBuffer->WriteToMessageParcel(static_cast<MessageParcel&>(parcel));
1802 } else {
1803 if (!WriteImageData(parcel, bufferSize)) {
1804 IMAGE_LOGE("write pixel map buffer to parcel failed.");
1805 return false;
1806 }
1807 }
1808 #else
1809 if (!WriteImageData(parcel, bufferSize)) {
1810 IMAGE_LOGE("write pixel map buffer to parcel failed.");
1811 return false;
1812 }
1813 #endif
1814
1815 if (!WriteTransformDataToParcel(parcel)) {
1816 IMAGE_LOGE("write transformData to parcel failed.");
1817 return false;
1818 }
1819 if (!WriteAstcRealSizeToParcel(parcel)) {
1820 IMAGE_LOGE("write astcrealSize to parcel failed.");
1821 return false;
1822 }
1823 return true;
1824 }
1825
ReadImageInfo(Parcel & parcel,ImageInfo & imgInfo)1826 bool PixelMap::ReadImageInfo(Parcel &parcel, ImageInfo &imgInfo)
1827 {
1828 imgInfo.size.width = parcel.ReadInt32();
1829 IMAGE_LOGD("read pixel map width:[%{public}d] to parcel.", imgInfo.size.width);
1830 imgInfo.size.height = parcel.ReadInt32();
1831 IMAGE_LOGD("read pixel map height:[%{public}d] to parcel.", imgInfo.size.height);
1832 imgInfo.pixelFormat = static_cast<PixelFormat>(parcel.ReadInt32());
1833 IMAGE_LOGD("read pixel map pixelFormat:[%{public}d] to parcel.", imgInfo.pixelFormat);
1834 imgInfo.colorSpace = static_cast<ColorSpace>(parcel.ReadInt32());
1835 IMAGE_LOGD("read pixel map colorSpace:[%{public}d] to parcel.", imgInfo.colorSpace);
1836 imgInfo.alphaType = static_cast<AlphaType>(parcel.ReadInt32());
1837 IMAGE_LOGD("read pixel map alphaType:[%{public}d] to parcel.", imgInfo.alphaType);
1838 imgInfo.baseDensity = parcel.ReadInt32();
1839 return true;
1840 }
1841
ReadTransformData(Parcel & parcel,PixelMap * pixelMap)1842 bool PixelMap::ReadTransformData(Parcel &parcel, PixelMap *pixelMap)
1843 {
1844 if (pixelMap->IsAstc()) {
1845 TransformData transformData;
1846 transformData.scaleX = parcel.ReadFloat();
1847 transformData.scaleY = parcel.ReadFloat();
1848 transformData.rotateD = parcel.ReadFloat();
1849 transformData.cropLeft = parcel.ReadFloat();
1850 transformData.cropTop = parcel.ReadFloat();
1851 transformData.cropWidth = parcel.ReadFloat();
1852 transformData.cropHeight = parcel.ReadFloat();
1853 transformData.translateX = parcel.ReadFloat();
1854 transformData.translateY = parcel.ReadFloat();
1855 transformData.flipX = parcel.ReadBool();
1856 transformData.flipY = parcel.ReadBool();
1857 pixelMap->SetTransformData(transformData);
1858 }
1859 return true;
1860 }
1861
ReadAstcRealSize(Parcel & parcel,PixelMap * pixelMap)1862 bool PixelMap::ReadAstcRealSize(Parcel &parcel, PixelMap *pixelMap)
1863 {
1864 if (pixelMap->IsAstc()) {
1865 Size realSize;
1866 realSize.width = parcel.ReadInt32();
1867 realSize.height = parcel.ReadInt32();
1868 pixelMap->SetAstcRealSize(realSize);
1869 }
1870 return true;
1871 }
1872
Unmarshalling(Parcel & parcel)1873 PixelMap *PixelMap::Unmarshalling(Parcel &parcel)
1874 {
1875 PIXEL_MAP_ERR error;
1876 PixelMap* dstPixelMap = PixelMap::Unmarshalling(parcel, error);
1877 if (dstPixelMap == nullptr || error.errorCode != SUCCESS) {
1878 IMAGE_LOGE("unmarshalling failed errorCode:%{public}d, errorInfo:%{public}s",
1879 error.errorCode, error.errorInfo.c_str());
1880 }
1881 return dstPixelMap;
1882 }
1883
Unmarshalling(Parcel & parcel,PIXEL_MAP_ERR & error)1884 PixelMap *PixelMap::Unmarshalling(Parcel &parcel, PIXEL_MAP_ERR &error)
1885 {
1886 PixelMap *pixelMap = new PixelMap();
1887 if (pixelMap == nullptr) {
1888 PixelMap::ConstructPixelMapError(error, ERR_IMAGE_PIXELMAP_CREATE_FAILED, "pixelmap create failed");
1889 return nullptr;
1890 }
1891
1892 ImageInfo imgInfo;
1893 if (!pixelMap->ReadImageInfo(parcel, imgInfo)) {
1894 IMAGE_LOGE("read imageInfo fail");
1895 delete pixelMap;
1896 PixelMap::ConstructPixelMapError(error, ERR_IMAGE_READ_PIXELMAP_FAILED, "read pixelmap failed");
1897 return nullptr;
1898 }
1899
1900 bool isEditable = parcel.ReadBool();
1901 pixelMap->SetEditable(isEditable);
1902
1903 bool isAstc = parcel.ReadBool();
1904 pixelMap->SetAstc(isAstc);
1905
1906 AllocatorType allocType = static_cast<AllocatorType>(parcel.ReadInt32());
1907 int32_t csm = parcel.ReadInt32();
1908 if (csm != ERR_MEDIA_INVALID_VALUE) {
1909 OHOS::ColorManager::ColorSpaceName colorSpaceName = static_cast<OHOS::ColorManager::ColorSpaceName>(csm);
1910 OHOS::ColorManager::ColorSpace grColorSpace = OHOS::ColorManager::ColorSpace(colorSpaceName);
1911 pixelMap->InnerSetColorSpace(grColorSpace);
1912 }
1913 int32_t rowDataSize = parcel.ReadInt32();
1914 int32_t bufferSize = parcel.ReadInt32();
1915 int32_t bytesPerPixel = ImageUtils::GetPixelBytes(imgInfo.pixelFormat);
1916 if (bytesPerPixel == 0) {
1917 delete pixelMap;
1918 IMAGE_LOGE("unmarshalling get bytes by per pixel fail.");
1919 return nullptr;
1920 }
1921 if ((!isAstc) && bufferSize != rowDataSize * imgInfo.size.height) {
1922 delete pixelMap;
1923 IMAGE_LOGE("unmarshalling bufferSize parcelling error");
1924 PixelMap::ConstructPixelMapError(error, ERR_IMAGE_BUFFER_SIZE_PARCEL_ERROR,
1925 "unmarshalling bufferSize parcelling error");
1926 return nullptr;
1927 }
1928 uint8_t *base = nullptr;
1929 void *context = nullptr;
1930 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(A_PLATFORM)
1931 if (allocType == AllocatorType::SHARE_MEM_ALLOC) {
1932 int fd = ReadFileDescriptor(parcel);
1933 if (fd < 0) {
1934 IMAGE_LOGE("fd < 0");
1935 delete pixelMap;
1936 PixelMap::ConstructPixelMapError(error, ERR_IMAGE_GET_FD_BAD, "fd acquisition failed");
1937 return nullptr;
1938 }
1939 void* ptr = ::mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1940 if (ptr == MAP_FAILED) {
1941 ptr = ::mmap(nullptr, bufferSize, PROT_READ, MAP_SHARED, fd, 0);
1942 if (ptr == MAP_FAILED) {
1943 ::close(fd);
1944 delete pixelMap;
1945 IMAGE_LOGE("shared memory map in memalloc failed, errno:%{public}d", errno);
1946 PixelMap::ConstructPixelMapError(error, ERR_IMAGE_GET_FD_BAD, "shared memory map in memalloc failed");
1947 return nullptr;
1948 }
1949 }
1950 context = new int32_t();
1951 if (context == nullptr) {
1952 ::munmap(ptr, bufferSize);
1953 ::close(fd);
1954 delete pixelMap;
1955 return nullptr;
1956 }
1957 *static_cast<int32_t *>(context) = fd;
1958 base = static_cast<uint8_t *>(ptr);
1959 } else if (allocType == AllocatorType::DMA_ALLOC) {
1960 sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
1961 surfaceBuffer->ReadFromMessageParcel(static_cast<MessageParcel&>(parcel));
1962 uint8_t* virAddr = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
1963 void* nativeBuffer = surfaceBuffer.GetRefPtr();
1964 ImageUtils::SurfaceBuffer_Reference(nativeBuffer);
1965 base = virAddr;
1966 context = nativeBuffer;
1967 } else {
1968 base = ReadImageData(parcel, bufferSize);
1969 if (base == nullptr) {
1970 IMAGE_LOGE("get pixel memory size:[%{public}d] error.", bufferSize);
1971 delete pixelMap;
1972 PixelMap::ConstructPixelMapError(error, ERR_IMAGE_GET_DATA_ABNORMAL, "ReadImageData failed");
1973 return nullptr;
1974 }
1975 }
1976 #else
1977 base = ReadImageData(parcel, bufferSize);
1978 if (base == nullptr) {
1979 IMAGE_LOGE("get pixel memory size:[%{public}d] error.", bufferSize);
1980 delete pixelMap;
1981 return nullptr;
1982 }
1983 #endif
1984
1985 uint32_t ret = pixelMap->SetImageInfo(imgInfo);
1986 if (ret != SUCCESS) {
1987 if (pixelMap->freePixelMapProc_ != nullptr) {
1988 pixelMap->freePixelMapProc_(base, context, bufferSize);
1989 }
1990 ReleaseMemory(allocType, base, context, bufferSize);
1991 if (allocType == AllocatorType::SHARE_MEM_ALLOC && context != nullptr) {
1992 delete static_cast<int32_t *>(context);
1993 }
1994 delete pixelMap;
1995 IMAGE_LOGE("create pixel map from parcel failed, set image info error.");
1996 return nullptr;
1997 }
1998 pixelMap->SetPixelsAddr(base, context, bufferSize, allocType, nullptr);
1999 if (!pixelMap->ReadTransformData(parcel, pixelMap)) {
2000 IMAGE_LOGE("read transformData fail");
2001 delete pixelMap;
2002 return nullptr;
2003 }
2004 if (!pixelMap->ReadAstcRealSize(parcel, pixelMap)) {
2005 IMAGE_LOGE("read astcrealSize fail");
2006 delete pixelMap;
2007 return nullptr;
2008 }
2009 return pixelMap;
2010 }
2011
WriteUint8(std::vector<uint8_t> & buff,uint8_t value) const2012 void PixelMap::WriteUint8(std::vector<uint8_t> &buff, uint8_t value) const
2013 {
2014 buff.push_back(value);
2015 }
2016
ReadUint8(std::vector<uint8_t> & buff,int32_t & cursor)2017 uint8_t PixelMap::ReadUint8(std::vector<uint8_t> &buff, int32_t &cursor)
2018 {
2019 if (static_cast<size_t>(cursor + 1) > buff.size()) {
2020 IMAGE_LOGE("ReadUint8 out of range");
2021 return TLV_END;
2022 }
2023 return buff[cursor++];
2024 }
2025
GetVarintLen(int32_t value) const2026 uint8_t PixelMap::GetVarintLen(int32_t value) const
2027 {
2028 uint8_t len = 1;
2029 while (value > TLV_VARINT_MASK) {
2030 len++;
2031 value >>= TLV_VARINT_BITS;
2032 }
2033 return len;
2034 }
2035
WriteVarint(std::vector<uint8_t> & buff,int32_t value) const2036 void PixelMap::WriteVarint(std::vector<uint8_t> &buff, int32_t value) const
2037 {
2038 while (value > TLV_VARINT_MASK) {
2039 buff.push_back(TLV_VARINT_MORE | uint8_t(value & TLV_VARINT_MASK));
2040 value >>= TLV_VARINT_BITS;
2041 }
2042 buff.push_back(uint8_t(value));
2043 }
2044
ReadVarint(std::vector<uint8_t> & buff,int32_t & cursor)2045 int32_t PixelMap::ReadVarint(std::vector<uint8_t> &buff, int32_t &cursor)
2046 {
2047 int32_t value = 0;
2048 uint8_t shift = 0;
2049 int32_t item = 0;
2050 do {
2051 if (static_cast<size_t>(cursor + 1) > buff.size()) {
2052 IMAGE_LOGE("ReadVarint out of range");
2053 return static_cast<int32_t>(TLV_END);
2054 }
2055 item = int32_t(buff[cursor++]);
2056 value |= (item & TLV_VARINT_MASK) << shift;
2057 shift += TLV_VARINT_BITS;
2058 } while ((item & TLV_VARINT_MORE) != 0);
2059 return value;
2060 }
2061
WriteData(std::vector<uint8_t> & buff,const uint8_t * data,const int32_t & height,const int32_t & rowDataSize,const int32_t & rowStride) const2062 void PixelMap::WriteData(std::vector<uint8_t> &buff, const uint8_t *data,
2063 const int32_t &height, const int32_t &rowDataSize, const int32_t &rowStride) const
2064 {
2065 if (allocatorType_ == AllocatorType::DMA_ALLOC) {
2066 for (int row = 0; row < height; row++) {
2067 for (int col = 0; col < rowDataSize; col++) {
2068 buff.push_back(*(data + row * rowStride + col));
2069 }
2070 }
2071 } else {
2072 int32_t size = pixelsSize_;
2073 for (int32_t offset = 0; offset < size; offset++) {
2074 buff.push_back(*(data + offset));
2075 }
2076 }
2077 }
2078
ReadData(std::vector<uint8_t> & buff,int32_t size,int32_t & cursor)2079 uint8_t *PixelMap::ReadData(std::vector<uint8_t> &buff, int32_t size, int32_t &cursor)
2080 {
2081 if (size <= 0) {
2082 IMAGE_LOGE("pixel map tlv read data fail: invalid size[%{public}d]", size);
2083 return nullptr;
2084 }
2085 if (static_cast<size_t>(cursor + size) > buff.size()) {
2086 IMAGE_LOGE("ReadData out of range");
2087 return nullptr;
2088 }
2089 uint8_t *data = static_cast<uint8_t *>(malloc(size));
2090 if (data == nullptr) {
2091 IMAGE_LOGE("pixel map tlv read data fail: malloc memory size[%{public}d]", size);
2092 return nullptr;
2093 }
2094 for (int32_t offset = 0; offset < size; offset++) {
2095 *(data + offset) = buff[cursor++];
2096 }
2097 return data;
2098 }
2099
EncodeTlv(std::vector<uint8_t> & buff) const2100 bool PixelMap::EncodeTlv(std::vector<uint8_t> &buff) const
2101 {
2102 WriteUint8(buff, TLV_IMAGE_WIDTH);
2103 WriteVarint(buff, GetVarintLen(imageInfo_.size.width));
2104 WriteVarint(buff, imageInfo_.size.width);
2105 WriteUint8(buff, TLV_IMAGE_HEIGHT);
2106 WriteVarint(buff, GetVarintLen(imageInfo_.size.height));
2107 WriteVarint(buff, imageInfo_.size.height);
2108 WriteUint8(buff, TLV_IMAGE_PIXELFORMAT);
2109 WriteVarint(buff, GetVarintLen(static_cast<int32_t>(imageInfo_.pixelFormat)));
2110 WriteVarint(buff, static_cast<int32_t>(imageInfo_.pixelFormat));
2111 WriteUint8(buff, TLV_IMAGE_COLORSPACE);
2112 WriteVarint(buff, GetVarintLen(static_cast<int32_t>(imageInfo_.colorSpace)));
2113 WriteVarint(buff, static_cast<int32_t>(imageInfo_.colorSpace));
2114 WriteUint8(buff, TLV_IMAGE_ALPHATYPE);
2115 WriteVarint(buff, GetVarintLen(static_cast<int32_t>(imageInfo_.alphaType)));
2116 WriteVarint(buff, static_cast<int32_t>(imageInfo_.alphaType));
2117 WriteUint8(buff, TLV_IMAGE_BASEDENSITY);
2118 WriteVarint(buff, GetVarintLen(imageInfo_.baseDensity));
2119 WriteVarint(buff, imageInfo_.baseDensity);
2120 WriteUint8(buff, TLV_IMAGE_ALLOCATORTYPE);
2121 AllocatorType tmpAllocatorType = AllocatorType::HEAP_ALLOC;
2122 WriteVarint(buff, GetVarintLen(static_cast<int32_t>(tmpAllocatorType)));
2123 WriteVarint(buff, static_cast<int32_t>(tmpAllocatorType));
2124 WriteUint8(buff, TLV_IMAGE_DATA);
2125 const uint8_t *data = data_;
2126 int32_t dataSize = rowDataSize_ * imageInfo_.size.height;
2127 if (data == nullptr || size_t(dataSize) > MAX_IMAGEDATA_SIZE || dataSize <= 0) {
2128 WriteVarint(buff, 0); // L is zero and no value
2129 WriteUint8(buff, TLV_END); // end tag
2130 IMAGE_LOGE("pixel map tlv encode fail: no data");
2131 return false;
2132 }
2133 WriteVarint(buff, dataSize);
2134 WriteData(buff, data, imageInfo_.size.height, rowDataSize_, rowStride_);
2135 WriteUint8(buff, TLV_END); // end tag
2136 return true;
2137 }
2138
ReadTlvAttr(std::vector<uint8_t> & buff,ImageInfo & info,int32_t & type,int32_t & size,uint8_t ** data)2139 void PixelMap::ReadTlvAttr(std::vector<uint8_t> &buff, ImageInfo &info, int32_t &type, int32_t &size, uint8_t **data)
2140 {
2141 int cursor = 0;
2142 for (uint8_t tag = ReadUint8(buff, cursor); tag != TLV_END; tag = ReadUint8(buff, cursor)) {
2143 int32_t len = ReadVarint(buff, cursor);
2144 if (len <= 0 || static_cast<size_t>(cursor + len) > buff.size()) {
2145 IMAGE_LOGE("ReadTlvAttr out of range");
2146 return;
2147 }
2148 switch (tag) {
2149 case TLV_IMAGE_WIDTH:
2150 info.size.width = ReadVarint(buff, cursor);
2151 break;
2152 case TLV_IMAGE_HEIGHT:
2153 info.size.height = ReadVarint(buff, cursor);
2154 break;
2155 case TLV_IMAGE_PIXELFORMAT:
2156 info.pixelFormat = static_cast<PixelFormat>(ReadVarint(buff, cursor));
2157 break;
2158 case TLV_IMAGE_COLORSPACE:
2159 info.colorSpace = static_cast<ColorSpace>(ReadVarint(buff, cursor));
2160 break;
2161 case TLV_IMAGE_ALPHATYPE:
2162 info.alphaType = static_cast<AlphaType>(ReadVarint(buff, cursor));
2163 break;
2164 case TLV_IMAGE_BASEDENSITY:
2165 info.baseDensity = ReadVarint(buff, cursor);
2166 break;
2167 case TLV_IMAGE_ALLOCATORTYPE:
2168 type = ReadVarint(buff, cursor);
2169 IMAGE_LOGI("pixel alloctype: %{public}d", type);
2170 break;
2171 case TLV_IMAGE_DATA:
2172 size = len;
2173 *data = ReadData(buff, size, cursor);
2174 break;
2175 default:
2176 cursor += len; // skip unknown tag
2177 IMAGE_LOGW("pixel map tlv decode warn: unknown tag[%{public}d]", tag);
2178 break;
2179 }
2180 }
2181 }
2182
DecodeTlv(std::vector<uint8_t> & buff)2183 PixelMap *PixelMap::DecodeTlv(std::vector<uint8_t> &buff)
2184 {
2185 PixelMap *pixelMap = new PixelMap();
2186 if (pixelMap == nullptr) {
2187 IMAGE_LOGE("pixel map tlv decode fail: new PixelMap error");
2188 return nullptr;
2189 }
2190 ImageInfo imageInfo;
2191 int32_t dataSize = 0;
2192 uint8_t *data = nullptr;
2193 int32_t allocType = static_cast<int32_t>(AllocatorType::DEFAULT);
2194 ReadTlvAttr(buff, imageInfo, allocType, dataSize, &data);
2195 if (data == nullptr) {
2196 delete pixelMap;
2197 IMAGE_LOGE("pixel map tlv decode fail: no data");
2198 return nullptr;
2199 }
2200 uint32_t ret = pixelMap->SetImageInfo(imageInfo);
2201 if (ret != SUCCESS) {
2202 free(data);
2203 delete pixelMap;
2204 IMAGE_LOGE("pixel map tlv decode fail: set image info error[%{public}d]", ret);
2205 return nullptr;
2206 }
2207 if (dataSize != pixelMap->GetByteCount()) {
2208 delete pixelMap;
2209 IMAGE_LOGE("pixel map tlv decode fail: dataSize not match");
2210 return nullptr;
2211 }
2212 pixelMap->SetPixelsAddr(data, nullptr, dataSize, static_cast<AllocatorType>(allocType), nullptr);
2213 return pixelMap;
2214 }
2215
GetNamedAlphaType(const AlphaType alphaType)2216 static const string GetNamedAlphaType(const AlphaType alphaType)
2217 {
2218 switch (alphaType) {
2219 case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
2220 return "Alpha Type Unknown";
2221 case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
2222 return "Alpha Type Opaque";
2223 case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
2224 return "Alpha Type Premul";
2225 case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
2226 return "Alpha Type Unpremul";
2227 default:
2228 return "Alpha Type Unknown";
2229 }
2230 return "Alpha Type Unknown";
2231 }
2232
GetNamedPixelFormat(const PixelFormat pixelFormat)2233 static const string GetNamedPixelFormat(const PixelFormat pixelFormat)
2234 {
2235 switch (pixelFormat) {
2236 case PixelFormat::UNKNOWN:
2237 return "Pixel Format UNKNOWN";
2238 case PixelFormat::RGB_565:
2239 return "Pixel Format RGB_565";
2240 case PixelFormat::RGB_888:
2241 return "Pixel Format RGB_888";
2242 case PixelFormat::NV21:
2243 return "Pixel Format NV21";
2244 case PixelFormat::NV12:
2245 return "Pixel Format NV12";
2246 case PixelFormat::CMYK:
2247 return "Pixel Format CMYK";
2248 case PixelFormat::ARGB_8888:
2249 return "Pixel Format ARGB_8888";
2250 case PixelFormat::ALPHA_8:
2251 return "Pixel Format ALPHA_8";
2252 case PixelFormat::RGBA_8888:
2253 return "Pixel Format RGBA_8888";
2254 case PixelFormat::BGRA_8888:
2255 return "Pixel Format BGRA_8888";
2256 case PixelFormat::RGBA_F16:
2257 return "Pixel Format RGBA_F16";
2258 case PixelFormat::ASTC_4x4:
2259 return "Pixel Format ASTC_4x4";
2260 case PixelFormat::ASTC_6x6:
2261 return "Pixel Format ASTC_6x6";
2262 case PixelFormat::ASTC_8x8:
2263 return "Pixel Format ASTC_8x8";
2264 default:
2265 return "Pixel Format UNKNOWN";
2266 }
2267 return "Pixel Format UNKNOWN";
2268 }
2269
2270 constexpr uint8_t HALF_LOW_BYTE = 0;
2271 constexpr uint8_t HALF_HIGH_BYTE = 1;
2272
HalfTranslate(const uint8_t * ui)2273 static float HalfTranslate(const uint8_t* ui)
2274 {
2275 return HalfToFloat(U8ToU16(ui[HALF_HIGH_BYTE], ui[HALF_LOW_BYTE]));
2276 }
2277
HalfTranslate(const float pixel,uint8_t * ui)2278 static void HalfTranslate(const float pixel, uint8_t* ui)
2279 {
2280 uint16_t val = FloatToHalf(pixel);
2281 ui[HALF_LOW_BYTE] = static_cast<uint8_t>((val >> SHIFT_8_BIT) & UINT8_MAX);
2282 ui[HALF_HIGH_BYTE] = static_cast<uint8_t>(val & UINT8_MAX);
2283 }
2284 constexpr uint8_t RGBA_F16_R_OFFSET = 0;
2285 constexpr uint8_t RGBA_F16_G_OFFSET = 2;
2286 constexpr uint8_t RGBA_F16_B_OFFSET = 4;
2287 constexpr uint8_t RGBA_F16_A_OFFSET = 6;
2288
2289 static constexpr float FLOAT_NUMBER_NEAR_ZERO = 0.000001;
2290 static constexpr float FLOAT_ZERO = 0.0f;
ProcessPremulF16Pixel(float mulPixel,float alpha,const float percent)2291 static float ProcessPremulF16Pixel(float mulPixel, float alpha, const float percent)
2292 {
2293 if (alpha < FLOAT_NUMBER_NEAR_ZERO && alpha > -FLOAT_NUMBER_NEAR_ZERO) {
2294 return FLOAT_ZERO;
2295 }
2296 float res = mulPixel * percent / alpha;
2297 return res > MAX_HALF ? MAX_HALF : res;
2298 }
2299
SetF16PixelAlpha(uint8_t * pixel,const float percent,bool isPixelPremul)2300 static void SetF16PixelAlpha(uint8_t *pixel, const float percent, bool isPixelPremul)
2301 {
2302 float a = HalfTranslate(pixel + RGBA_F16_A_OFFSET);
2303 if (isPixelPremul) {
2304 float r = HalfTranslate(pixel + RGBA_F16_R_OFFSET);
2305 float g = HalfTranslate(pixel + RGBA_F16_G_OFFSET);
2306 float b = HalfTranslate(pixel + RGBA_F16_B_OFFSET);
2307 r = ProcessPremulF16Pixel(r, a, percent);
2308 g = ProcessPremulF16Pixel(g, a, percent);
2309 b = ProcessPremulF16Pixel(b, a, percent);
2310 HalfTranslate(r, pixel + RGBA_F16_R_OFFSET);
2311 HalfTranslate(g, pixel + RGBA_F16_G_OFFSET);
2312 HalfTranslate(b, pixel + RGBA_F16_B_OFFSET);
2313 }
2314 a = percent * MAX_HALF;
2315 HalfTranslate(a, pixel + RGBA_F16_A_OFFSET);
2316 }
2317
2318 static constexpr uint8_t U_ZERO = 0;
ProcessPremulPixel(uint8_t mulPixel,uint8_t alpha,const float percent)2319 static uint8_t ProcessPremulPixel(uint8_t mulPixel, uint8_t alpha, const float percent)
2320 {
2321 // mP = oP * oAlpha / UINT8_MAX
2322 // => oP = mP * UINT8_MAX / oAlpha
2323 // nP = oP * percent
2324 // => nP = mP * UINT8_MAX * percent / oAlpha
2325 if (alpha == 0) {
2326 return U_ZERO;
2327 }
2328 float nPixel = mulPixel * percent * UINT8_MAX / alpha;
2329 if ((nPixel + HALF_ONE) >= UINT8_MAX) {
2330 return UINT8_MAX;
2331 }
2332 return static_cast<uint8_t>(nPixel + HALF_ONE);
2333 }
2334
SetUintPixelAlpha(uint8_t * pixel,const float percent,uint8_t pixelByte,int8_t alphaIndex,bool isPixelPremul)2335 static void SetUintPixelAlpha(uint8_t *pixel, const float percent,
2336 uint8_t pixelByte, int8_t alphaIndex, bool isPixelPremul)
2337 {
2338 if (isPixelPremul) {
2339 for (int32_t pixelIndex = 0; pixelIndex < pixelByte; pixelIndex++) {
2340 if (pixelIndex != alphaIndex) {
2341 pixel[pixelIndex] = ProcessPremulPixel(pixel[pixelIndex],
2342 pixel[alphaIndex], percent);
2343 }
2344 }
2345 }
2346 pixel[alphaIndex] = static_cast<uint8_t>(UINT8_MAX * percent + HALF_ONE);
2347 }
2348
GetAlphaIndex(const PixelFormat & pixelFormat)2349 static int8_t GetAlphaIndex(const PixelFormat& pixelFormat)
2350 {
2351 switch (pixelFormat) {
2352 case PixelFormat::ARGB_8888:
2353 case PixelFormat::ALPHA_8:
2354 return ARGB_ALPHA_INDEX;
2355 case PixelFormat::RGBA_8888:
2356 case PixelFormat::BGRA_8888:
2357 case PixelFormat::RGBA_F16:
2358 return BGRA_ALPHA_INDEX;
2359 default:
2360 return INVALID_ALPHA_INDEX;
2361 }
2362 }
2363
SetAlpha(const float percent)2364 uint32_t PixelMap::SetAlpha(const float percent)
2365 {
2366 auto alphaType = GetAlphaType();
2367 if (alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN ||
2368 alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
2369 IMAGE_LOGE(
2370 "Could not set alpha on %{public}s",
2371 GetNamedAlphaType(alphaType).c_str());
2372 return ERR_IMAGE_DATA_UNSUPPORT;
2373 }
2374
2375 if (percent <= 0 || percent > 1) {
2376 IMAGE_LOGE(
2377 "Set alpha input should (0 < input <= 1). Current input %{public}f",
2378 percent);
2379 return ERR_IMAGE_INVALID_PARAMETER;
2380 }
2381
2382 bool isPixelPremul = alphaType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
2383 auto pixelFormat = GetPixelFormat();
2384 uint32_t pixelsSize = GetByteCount();
2385 int8_t alphaIndex = GetAlphaIndex(pixelFormat);
2386 if (alphaIndex == INVALID_ALPHA_INDEX) {
2387 IMAGE_LOGE("Could not set alpha on %{public}s",
2388 GetNamedPixelFormat(pixelFormat).c_str());
2389 return ERR_IMAGE_DATA_UNSUPPORT;
2390 }
2391
2392 if ((pixelFormat == PixelFormat::ALPHA_8 && pixelBytes_ != ALPHA_BYTES) ||
2393 (pixelFormat == PixelFormat::RGBA_F16 && pixelBytes_ != RGBA_F16_BYTES)) {
2394 IMAGE_LOGE("Pixel format %{public}s mismatch pixelByte %{public}d",
2395 GetNamedPixelFormat(pixelFormat).c_str(), pixelBytes_);
2396 return ERR_IMAGE_INVALID_PARAMETER;
2397 }
2398 for (uint32_t i = 0; i < pixelsSize;) {
2399 uint8_t* pixel = data_ + i;
2400 if (pixelFormat == PixelFormat::RGBA_F16) {
2401 SetF16PixelAlpha(pixel, percent, isPixelPremul);
2402 } else {
2403 SetUintPixelAlpha(pixel, percent, pixelBytes_, alphaIndex, isPixelPremul);
2404 }
2405 i += pixelBytes_;
2406 }
2407 return SUCCESS;
2408 }
2409
ToSkColorSpace(PixelMap * pixelmap)2410 static sk_sp<SkColorSpace> ToSkColorSpace(PixelMap *pixelmap)
2411 {
2412 #ifdef IMAGE_COLORSPACE_FLAG
2413 if (pixelmap->InnerGetGrColorSpacePtr() == nullptr) {
2414 return nullptr;
2415 }
2416 return pixelmap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
2417 #else
2418 return nullptr;
2419 #endif
2420 }
2421
ToSkImageInfo(ImageInfo & info,sk_sp<SkColorSpace> colorSpace)2422 static SkImageInfo ToSkImageInfo(ImageInfo &info, sk_sp<SkColorSpace> colorSpace)
2423 {
2424 SkColorType colorType = ImageTypeConverter::ToSkColorType(info.pixelFormat);
2425 SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(info.alphaType);
2426 IMAGE_LOGD("ToSkImageInfo w %{public}d, h %{public}d", info.size.width, info.size.height);
2427 IMAGE_LOGD(
2428 "ToSkImageInfo pf %{public}s, at %{public}s, skpf %{public}s, skat %{public}s",
2429 ImageTypeConverter::ToName(info.pixelFormat).c_str(),
2430 ImageTypeConverter::ToName(info.alphaType).c_str(),
2431 ImageTypeConverter::ToName(colorType).c_str(),
2432 ImageTypeConverter::ToName(alphaType).c_str()
2433 );
2434 return SkImageInfo::Make(info.size.width, info.size.height, colorType, alphaType, colorSpace);
2435 }
2436
ToImageInfo(ImageInfo & info,SkImageInfo & skInfo,bool sizeOnly=true)2437 static void ToImageInfo(ImageInfo &info, SkImageInfo &skInfo, bool sizeOnly = true)
2438 {
2439 info.size.width = skInfo.width();
2440 info.size.height = skInfo.height();
2441 if (!sizeOnly) {
2442 info.alphaType = ImageTypeConverter::ToAlphaType(skInfo.alphaType());
2443 info.pixelFormat = ImageTypeConverter::ToPixelFormat(skInfo.colorType());
2444 }
2445 }
2446
2447 struct SkTransInfo {
2448 SkRect r;
2449 SkImageInfo info;
2450 SkBitmap bitmap;
2451 };
2452
2453 struct TransMemoryInfo {
2454 AllocatorType allocType;
2455 std::unique_ptr<AbsMemory> memory = nullptr;
2456 };
2457
2458 constexpr float HALF = 0.5f;
2459
FloatToInt(float a)2460 static inline int FloatToInt(float a)
2461 {
2462 return static_cast<int>(a + HALF);
2463 }
2464
2465 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
GenSrcTransInfo(SkTransInfo & srcInfo,ImageInfo & imageInfo,PixelMap * pixelmap,sk_sp<SkColorSpace> colorSpace)2466 static void GenSrcTransInfo(SkTransInfo &srcInfo, ImageInfo &imageInfo, PixelMap* pixelmap,
2467 sk_sp<SkColorSpace> colorSpace)
2468 {
2469 srcInfo.r = SkRect::MakeIWH(imageInfo.size.width, imageInfo.size.height);
2470 srcInfo.info = ToSkImageInfo(imageInfo, colorSpace);
2471 uint64_t rowStride = srcInfo.info.minRowBytes();
2472 if (pixelmap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
2473 if (pixelmap->GetFd() == nullptr) {
2474 IMAGE_LOGE("GenSrcTransInfo get surfacebuffer failed");
2475 }
2476 SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(pixelmap->GetFd());
2477 rowStride = sbBuffer->GetStride();
2478 }
2479 srcInfo.bitmap.installPixels(srcInfo.info, static_cast<uint8_t *>(pixelmap->GetWritablePixels()), rowStride);
2480 }
2481 #else
GenSrcTransInfo(SkTransInfo & srcInfo,ImageInfo & imageInfo,uint8_t * pixels,sk_sp<SkColorSpace> colorSpace)2482 static void GenSrcTransInfo(SkTransInfo &srcInfo, ImageInfo &imageInfo, uint8_t* pixels,
2483 sk_sp<SkColorSpace> colorSpace)
2484 {
2485 srcInfo.r = SkRect::MakeIWH(imageInfo.size.width, imageInfo.size.height);
2486 srcInfo.info = ToSkImageInfo(imageInfo, colorSpace);
2487 srcInfo.bitmap.installPixels(srcInfo.info, pixels, srcInfo.info.minRowBytes());
2488 }
2489 #endif
2490
GendstTransInfo(SkTransInfo & srcInfo,SkTransInfo & dstInfo,SkMatrix & matrix,TransMemoryInfo & memoryInfo)2491 static bool GendstTransInfo(SkTransInfo &srcInfo, SkTransInfo &dstInfo, SkMatrix &matrix,
2492 TransMemoryInfo &memoryInfo)
2493 {
2494 dstInfo.r = matrix.mapRect(srcInfo.r);
2495 int width = FloatToInt(dstInfo.r.width());
2496 int height = FloatToInt(dstInfo.r.height());
2497 if (matrix.isTranslate()) {
2498 width += dstInfo.r.fLeft;
2499 height += dstInfo.r.fTop;
2500 }
2501 dstInfo.info = srcInfo.info.makeWH(width, height);
2502 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
2503 Size desiredSize = {dstInfo.info.width(), dstInfo.info.height()};
2504 MemoryData memoryData = {nullptr, dstInfo.info.computeMinByteSize(), "Trans ImageData", desiredSize};
2505 #else
2506 MemoryData memoryData = {nullptr, dstInfo.info.computeMinByteSize(), "Trans ImageData"};
2507 #endif
2508 std::unique_ptr<AbsMemory> dstMemory = MemoryManager::CreateMemory(memoryInfo.allocType, memoryData);
2509 if (dstMemory == nullptr) {
2510 IMAGE_LOGE("CreateMemory falied");
2511 return false;
2512 }
2513 memoryInfo.memory = std::move(dstMemory);
2514 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
2515 uint64_t rowStride = dstInfo.info.minRowBytes();
2516 if (memoryInfo.allocType == AllocatorType::DMA_ALLOC) {
2517 if (memoryInfo.memory->extend.data == nullptr) {
2518 IMAGE_LOGE("GendstTransInfo get surfacebuffer failed");
2519 }
2520 SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(memoryInfo.memory->extend.data);
2521 rowStride = sbBuffer->GetStride();
2522 }
2523 dstInfo.bitmap.installPixels(dstInfo.info, memoryInfo.memory->data.data, rowStride);
2524 #else
2525 dstInfo.bitmap.installPixels(dstInfo.info, memoryInfo.memory->data.data, dstInfo.info.minRowBytes());
2526 #endif
2527 return true;
2528 }
2529
2530 struct TransInfos {
2531 SkMatrix matrix;
2532 };
2533
IsSupportAntiAliasing(const ImageInfo & imageInfo,const AntiAliasingOption & option)2534 bool IsSupportAntiAliasing(const ImageInfo& imageInfo, const AntiAliasingOption &option)
2535 {
2536 return option != AntiAliasingOption::NONE && imageInfo.size.width <= ANTIALIASING_SIZE &&
2537 imageInfo.size.height <= ANTIALIASING_SIZE;
2538 }
2539
ToSkSamplingOption(const AntiAliasingOption & option)2540 SkSamplingOptions ToSkSamplingOption(const AntiAliasingOption &option)
2541 {
2542 switch (option) {
2543 case AntiAliasingOption::NONE: return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
2544 case AntiAliasingOption::LOW: return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
2545 case AntiAliasingOption::MEDIUM: return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
2546 case AntiAliasingOption::HIGH: return SkSamplingOptions(SkCubicResampler { 1 / 3.0f, 1 / 3.0f });
2547 default: return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
2548 }
2549 }
2550
DoTranslation(TransInfos & infos,const AntiAliasingOption & option)2551 bool PixelMap::DoTranslation(TransInfos &infos, const AntiAliasingOption &option)
2552 {
2553 ImageInfo imageInfo;
2554 GetImageInfo(imageInfo);
2555
2556 TransMemoryInfo dstMemory;
2557 if (allocatorType_ == AllocatorType::CUSTOM_ALLOC) {
2558 // We dont know how custom alloc memory
2559 dstMemory.allocType = AllocatorType::DEFAULT;
2560 } else {
2561 dstMemory.allocType = allocatorType_;
2562 }
2563
2564 SkTransInfo src;
2565 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
2566 GenSrcTransInfo(src, imageInfo, this, ToSkColorSpace(this));
2567 #else
2568 GenSrcTransInfo(src, imageInfo, data_, ToSkColorSpace(this));
2569 #endif
2570
2571 SkTransInfo dst;
2572 if (!GendstTransInfo(src, dst, infos.matrix, dstMemory)) {
2573 IMAGE_LOGE("GendstTransInfo dstMemory falied");
2574 this->errorCode = IMAGE_RESULT_DECODE_FAILED;
2575 return false;
2576 }
2577
2578 SkCanvas canvas(dst.bitmap);
2579 if (!infos.matrix.isTranslate()) {
2580 if (!EQUAL_TO_ZERO(dst.r.fLeft) || !EQUAL_TO_ZERO(dst.r.fTop)) {
2581 canvas.translate(-dst.r.fLeft, -dst.r.fTop);
2582 }
2583 }
2584 canvas.concat(infos.matrix);
2585 auto skimage = SkImage::MakeFromBitmap(src.bitmap);
2586 if (ImageSystemProperties::GetAntiAliasingEnabled() && IsSupportAntiAliasing(imageInfo, option)) {
2587 canvas.drawImage(skimage, FLOAT_ZERO, FLOAT_ZERO,
2588 SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear));
2589 } else {
2590 canvas.drawImage(skimage, FLOAT_ZERO, FLOAT_ZERO, ToSkSamplingOption(option));
2591 }
2592
2593 ToImageInfo(imageInfo, dst.info);
2594 #ifdef IMAGE_COLORSPACE_FLAG
2595 if (dst.bitmap.refColorSpace() != nullptr) {
2596 grColorSpace_ = make_shared<OHOS::ColorManager::ColorSpace>(dst.bitmap.refColorSpace());
2597 }
2598 #endif
2599 auto m = dstMemory.memory.get();
2600 SetPixelsAddr(m->data.data, m->extend.data, m->data.size, m->GetType(), nullptr);
2601 SetImageInfo(imageInfo, true);
2602 return true;
2603 }
2604
scale(float xAxis,float yAxis)2605 void PixelMap::scale(float xAxis, float yAxis)
2606 {
2607 ImageTrace imageTrace("PixelMap scale");
2608 TransInfos infos;
2609 infos.matrix.setScale(xAxis, yAxis);
2610 if (!DoTranslation(infos)) {
2611 IMAGE_LOGE("scale falied");
2612 }
2613 }
2614
scale(float xAxis,float yAxis,const AntiAliasingOption & option)2615 void PixelMap::scale(float xAxis, float yAxis, const AntiAliasingOption &option)
2616 {
2617 ImageTrace imageTrace("PixelMap scale");
2618 TransInfos infos;
2619 infos.matrix.setScale(xAxis, yAxis);
2620 if (!DoTranslation(infos, option)) {
2621 IMAGE_LOGE("scale falied");
2622 }
2623 }
2624
resize(float xAxis,float yAxis)2625 bool PixelMap::resize(float xAxis, float yAxis)
2626 {
2627 ImageTrace imageTrace("PixelMap resize");
2628 TransInfos infos;
2629 infos.matrix.setScale(xAxis, yAxis);
2630 if (!DoTranslation(infos)) {
2631 IMAGE_LOGE("resize falied");
2632 return false;
2633 }
2634 return true;
2635 }
2636
translate(float xAxis,float yAxis)2637 void PixelMap::translate(float xAxis, float yAxis)
2638 {
2639 ImageTrace imageTrace("PixelMap translate");
2640 TransInfos infos;
2641 infos.matrix.setTranslate(xAxis, yAxis);
2642 if (!DoTranslation(infos)) {
2643 IMAGE_LOGE("translate falied");
2644 }
2645 }
2646
rotate(float degrees)2647 void PixelMap::rotate(float degrees)
2648 {
2649 ImageTrace imageTrace("PixelMap rotate");
2650 TransInfos infos;
2651 infos.matrix.setRotate(degrees);
2652 if (!DoTranslation(infos)) {
2653 IMAGE_LOGE("rotate falied");
2654 }
2655 }
2656
flip(bool xAxis,bool yAxis)2657 void PixelMap::flip(bool xAxis, bool yAxis)
2658 {
2659 ImageTrace imageTrace("PixelMap flip");
2660 if (xAxis == false && yAxis == false) {
2661 return;
2662 }
2663 scale(xAxis ? -1 : 1, yAxis ? -1 : 1);
2664 }
2665
crop(const Rect & rect)2666 uint32_t PixelMap::crop(const Rect &rect)
2667 {
2668 ImageInfo imageInfo;
2669 GetImageInfo(imageInfo);
2670
2671 SkTransInfo src;
2672 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
2673 GenSrcTransInfo(src, imageInfo, this, ToSkColorSpace(this));
2674 #else
2675 GenSrcTransInfo(src, imageInfo, data_, ToSkColorSpace(this));
2676 #endif
2677
2678 SkTransInfo dst;
2679 SkIRect dstIRect = SkIRect::MakeXYWH(rect.left, rect.top, rect.width, rect.height);
2680 dst.r = SkRect::Make(dstIRect);
2681 if (dst.r == src.r) {
2682 return SUCCESS;
2683 }
2684
2685 if (!src.r.contains(dst.r)) {
2686 IMAGE_LOGE("Invalid crop rect");
2687 return ERR_IMAGE_CROP;
2688 }
2689 dst.info = src.info.makeWH(dstIRect.width(), dstIRect.height());
2690 Size desiredSize = {dst.info.width(), dst.info.height()};
2691 MemoryData memoryData = {nullptr, dst.info.computeMinByteSize(), "Trans ImageData", desiredSize};
2692 auto m = MemoryManager::CreateMemory(allocatorType_, memoryData);
2693 if (m == nullptr) {
2694 return ERR_IMAGE_CROP;
2695 }
2696 uint64_t rowStride = dst.info.minRowBytes();
2697 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
2698 if (allocatorType_ == AllocatorType::DMA_ALLOC) {
2699 if (m->extend.data == nullptr) {
2700 IMAGE_LOGE("GendstTransInfo get surfacebuffer failed");
2701 return ERR_IMAGE_CROP;
2702 }
2703 rowStride = reinterpret_cast<SurfaceBuffer*>(m->extend.data)->GetStride();
2704 }
2705 #endif
2706 if (!src.bitmap.readPixels(dst.info, m->data.data, rowStride, dstIRect.fLeft, dstIRect.fTop)) {
2707 IMAGE_LOGE("ReadPixels failed");
2708 return ERR_IMAGE_CROP;
2709 }
2710 ToImageInfo(imageInfo, dst.info);
2711 #ifdef IMAGE_COLORSPACE_FLAG
2712 if (dst.info.refColorSpace() != nullptr) {
2713 grColorSpace_ = make_shared<OHOS::ColorManager::ColorSpace>(dst.info.refColorSpace());
2714 }
2715 #endif
2716 SetPixelsAddr(m->data.data, m->extend.data, m->data.size, m->GetType(), nullptr);
2717 SetImageInfo(imageInfo, true);
2718 return SUCCESS;
2719 }
2720
2721 #ifdef IMAGE_COLORSPACE_FLAG
InnerSetColorSpace(const OHOS::ColorManager::ColorSpace & grColorSpace)2722 void PixelMap::InnerSetColorSpace(const OHOS::ColorManager::ColorSpace &grColorSpace)
2723 {
2724 grColorSpace_ = std::make_shared<OHOS::ColorManager::ColorSpace>(grColorSpace.ToSkColorSpace(),
2725 grColorSpace.GetColorSpaceName());
2726 }
2727
InnerGetGrColorSpace()2728 OHOS::ColorManager::ColorSpace PixelMap::InnerGetGrColorSpace()
2729 {
2730 if (grColorSpace_ == nullptr) {
2731 grColorSpace_ =
2732 std::make_shared<OHOS::ColorManager::ColorSpace>(OHOS::ColorManager::ColorSpaceName::SRGB);
2733 }
2734 return *grColorSpace_;
2735 }
2736
isSameColorSpace(const OHOS::ColorManager::ColorSpace & src,const OHOS::ColorManager::ColorSpace & dst)2737 static bool isSameColorSpace(const OHOS::ColorManager::ColorSpace &src,
2738 const OHOS::ColorManager::ColorSpace &dst)
2739 {
2740 auto skSrc = src.ToSkColorSpace();
2741 auto skDst = dst.ToSkColorSpace();
2742 return SkColorSpace::Equals(skSrc.get(), skDst.get());
2743 }
2744
ApplyColorSpace(const OHOS::ColorManager::ColorSpace & grColorSpace)2745 uint32_t PixelMap::ApplyColorSpace(const OHOS::ColorManager::ColorSpace &grColorSpace)
2746 {
2747 auto grName = grColorSpace.GetColorSpaceName();
2748 if (grColorSpace_ != nullptr && isSameColorSpace(*grColorSpace_, grColorSpace)) {
2749 if (grColorSpace_->GetColorSpaceName() != grName) {
2750 InnerSetColorSpace(grColorSpace);
2751 }
2752 return SUCCESS;
2753 }
2754 ImageInfo imageInfo;
2755 GetImageInfo(imageInfo);
2756 // Build sk source infomation
2757 SkTransInfo src;
2758 src.info = ToSkImageInfo(imageInfo, ToSkColorSpace(this));
2759 uint64_t rowStride = src.info.minRowBytes();
2760 uint8_t* srcData = data_;
2761 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
2762 if (GetAllocatorType() == AllocatorType::DMA_ALLOC && GetFd() != nullptr) {
2763 SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(GetFd());
2764 rowStride = sbBuffer->GetStride();
2765 }
2766 srcData = static_cast<uint8_t *>(GetWritablePixels());
2767 #endif
2768 src.bitmap.installPixels(src.info, srcData, rowStride);
2769 // Build sk target infomation
2770 SkTransInfo dst;
2771 dst.info = ToSkImageInfo(imageInfo, grColorSpace.ToSkColorSpace());
2772 MemoryData memoryData = {nullptr, dst.info.computeMinByteSize(),
2773 "Trans ImageData", {dst.info.width(), dst.info.height()}};
2774 auto m = MemoryManager::CreateMemory(allocatorType_, memoryData);
2775 if (m == nullptr) {
2776 IMAGE_LOGE("applyColorSpace CreateMemory failed");
2777 return ERR_IMAGE_COLOR_CONVERT;
2778 }
2779 // Transfor pixels by readPixels
2780 if (!src.bitmap.readPixels(dst.info, m->data.data, rowStride, 0, 0)) {
2781 m->Release();
2782 IMAGE_LOGE("ReadPixels failed");
2783 return ERR_IMAGE_COLOR_CONVERT;
2784 }
2785 // Restore target infomation into pixelmap
2786 ToImageInfo(imageInfo, dst.info);
2787 grColorSpace_ = std::make_shared<OHOS::ColorManager::ColorSpace>(dst.info.refColorSpace(), grName);
2788 SetPixelsAddr(m->data.data, m->extend.data, m->data.size, m->GetType(), nullptr);
2789 SetImageInfo(imageInfo, true);
2790 return SUCCESS;
2791 }
2792 #endif
2793 } // namespace Media
2794 } // namespace OHOS
2795