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