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