• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pixel_map.h"
17 #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 &region)
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 &region, 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 &region)
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