• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "pixel_map_impl.h"
16 
17 #include "image_format_convert.h"
18 #include "image_log.h"
19 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
20 #include <charconv>
21 #include <regex>
22 
23 #include "pixel_map_from_surface.h"
24 #include "sync_fence.h"
25 #include "transaction/rs_interfaces.h"
26 #endif
27 #include "image_utils.h"
28 #include "media_errors.h"
29 #include "message_sequence_impl.h"
30 
31 namespace {
32 constexpr uint32_t NUM_2 = 2;
33 }
34 
35 enum class FormatType : int8_t { UNKNOWN, YUV, RGB, ASTC };
36 
37 namespace OHOS {
38 namespace Media {
GetRealPixelMap()39 std::shared_ptr<PixelMap> PixelMapImpl::GetRealPixelMap()
40 {
41     return real_;
42 }
43 
CreatePixelMap(const InitializationOptions & opts)44 std::unique_ptr<PixelMap> PixelMapImpl::CreatePixelMap(const InitializationOptions& opts)
45 {
46     if (opts.pixelFormat == PixelFormat::RGBA_1010102 || opts.pixelFormat == PixelFormat::YCBCR_P010 ||
47         opts.pixelFormat == PixelFormat::YCRCB_P010) {
48         return nullptr;
49     }
50     std::unique_ptr<PixelMap> ptr_ = PixelMap::Create(opts);
51     if (ptr_ == nullptr) {
52         IMAGE_LOGE("[PixelMapImpl] instance init failed!");
53     }
54     return ptr_;
55 }
56 
CreatePixelMap(uint32_t * colors,uint32_t colorLength,InitializationOptions & opts)57 std::unique_ptr<PixelMap> PixelMapImpl::CreatePixelMap(
58     uint32_t* colors, uint32_t colorLength, InitializationOptions& opts)
59 {
60     if (opts.pixelFormat == PixelFormat::RGBA_1010102 || opts.pixelFormat == PixelFormat::YCBCR_P010 ||
61         opts.pixelFormat == PixelFormat::YCRCB_P010) {
62         return nullptr;
63     }
64     std::unique_ptr<PixelMap> ptr_ = PixelMap::Create(colors, colorLength, opts);
65     if (ptr_ == nullptr) {
66         IMAGE_LOGE("[PixelMapImpl] instance init failed!");
67     }
68     return ptr_;
69 }
70 
CreateAlphaPixelMap(PixelMap & source,InitializationOptions & opts)71 std::unique_ptr<PixelMap> PixelMapImpl::CreateAlphaPixelMap(PixelMap& source, InitializationOptions& opts)
72 {
73     std::unique_ptr<PixelMap> ptr_ = PixelMap::Create(source, opts);
74     if (ptr_ == nullptr) {
75         IMAGE_LOGE("[PixelMapImpl] instance init failed!");
76     }
77     return ptr_;
78 }
79 
CreatePremultipliedPixelMap(std::shared_ptr<PixelMap> src,std::shared_ptr<PixelMap> dst)80 uint32_t PixelMapImpl::CreatePremultipliedPixelMap(std::shared_ptr<PixelMap> src, std::shared_ptr<PixelMap> dst)
81 {
82     if (src == nullptr || dst == nullptr) {
83         return ERR_IMAGE_READ_PIXELMAP_FAILED;
84     } else {
85         bool isPremul = true;
86         if (dst->IsEditable()) {
87             return src->ConvertAlphaFormat(*dst.get(), isPremul);
88         } else {
89             return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
90         }
91     }
92 }
93 
CreateUnpremultipliedPixelMap(std::shared_ptr<PixelMap> src,std::shared_ptr<PixelMap> dst)94 uint32_t PixelMapImpl::CreateUnpremultipliedPixelMap(std::shared_ptr<PixelMap> src, std::shared_ptr<PixelMap> dst)
95 {
96     if (src == nullptr || dst == nullptr) {
97         return ERR_IMAGE_READ_PIXELMAP_FAILED;
98     } else {
99         bool isPremul = false;
100         if (dst->IsEditable()) {
101             return src->ConvertAlphaFormat(*dst.get(), isPremul);
102         } else {
103             return ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY;
104         }
105     }
106 }
107 
PixelMapImpl(std::shared_ptr<PixelMap> ptr_)108 PixelMapImpl::PixelMapImpl(std::shared_ptr<PixelMap> ptr_)
109 {
110     real_ = ptr_;
111 }
112 
ReadPixelsToBuffer(uint64_t & bufferSize,uint8_t * dst)113 uint32_t PixelMapImpl::ReadPixelsToBuffer(uint64_t& bufferSize, uint8_t* dst)
114 {
115     if (real_ == nullptr) {
116         return ERR_IMAGE_READ_PIXELMAP_FAILED;
117     }
118     return real_->ReadPixels(bufferSize, dst);
119 }
120 
ReadPixels(uint64_t & bufferSize,uint32_t & offset,uint32_t & stride,Rect & region,uint8_t * dst)121 uint32_t PixelMapImpl::ReadPixels(uint64_t& bufferSize, uint32_t& offset, uint32_t& stride, Rect& region, uint8_t* dst)
122 {
123     if (real_ == nullptr) {
124         return ERR_IMAGE_READ_PIXELMAP_FAILED;
125     }
126     return real_->ReadPixels(bufferSize, offset, stride, region, dst);
127 }
128 
WriteBufferToPixels(uint8_t * source,uint64_t & bufferSize)129 uint32_t PixelMapImpl::WriteBufferToPixels(uint8_t* source, uint64_t& bufferSize)
130 {
131     if (real_ == nullptr) {
132         return ERR_IMAGE_READ_PIXELMAP_FAILED;
133     }
134     return real_->WritePixels(source, bufferSize);
135 }
136 
WritePixels(uint8_t * source,uint64_t & bufferSize,uint32_t & offset,uint32_t & stride,Rect & region)137 uint32_t PixelMapImpl::WritePixels(
138     uint8_t* source, uint64_t& bufferSize, uint32_t& offset, uint32_t& stride, Rect& region)
139 {
140     if (real_ == nullptr) {
141         return ERR_IMAGE_READ_PIXELMAP_FAILED;
142     }
143     return real_->WritePixels(source, bufferSize, offset, stride, region);
144 }
145 
GetImageInfo(ImageInfo & imageInfo)146 void PixelMapImpl::GetImageInfo(ImageInfo& imageInfo)
147 {
148     if (real_ == nullptr) {
149         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
150         return;
151     }
152     real_->GetImageInfo(imageInfo);
153 }
154 
GetDensity()155 int32_t PixelMapImpl::GetDensity()
156 {
157     if (real_ == nullptr) {
158         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
159         return 0;
160     }
161     return real_->GetBaseDensity();
162 }
163 
Opacity(float percent)164 uint32_t PixelMapImpl::Opacity(float percent)
165 {
166     if (real_ == nullptr) {
167         return ERR_IMAGE_READ_PIXELMAP_FAILED;
168     }
169     return real_->SetAlpha(percent);
170 }
171 
Scale(float xAxis,float yAxis)172 void PixelMapImpl::Scale(float xAxis, float yAxis)
173 {
174     if (real_ == nullptr) {
175         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
176         return;
177     }
178     real_->scale(xAxis, yAxis);
179 }
180 
Scale(float xAxis,float yAxis,AntiAliasingOption option)181 void PixelMapImpl::Scale(float xAxis, float yAxis, AntiAliasingOption option)
182 {
183     if (real_ == nullptr) {
184         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
185         return;
186     }
187     real_->scale(xAxis, yAxis, option);
188 }
189 
Crop(Rect & rect)190 uint32_t PixelMapImpl::Crop(Rect& rect)
191 {
192     if (real_ == nullptr) {
193         return ERR_IMAGE_READ_PIXELMAP_FAILED;
194     }
195     return real_->crop(rect);
196 }
197 
ToSdr()198 uint32_t PixelMapImpl::ToSdr()
199 {
200     if (real_ == nullptr) {
201         return ERR_IMAGE_READ_PIXELMAP_FAILED;
202     }
203     if (!GetPixelMapImplEditable()) {
204         IMAGE_LOGE("ToSdrExec pixelmap is not editable");
205         return ERR_RESOURCE_UNAVAILABLE;
206     }
207     return real_->ToSdr();
208 }
209 
Flip(bool xAxis,bool yAxis)210 void PixelMapImpl::Flip(bool xAxis, bool yAxis)
211 {
212     if (real_ == nullptr) {
213         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
214         return;
215     }
216     real_->flip(xAxis, yAxis);
217 }
218 
Rotate(float degrees)219 void PixelMapImpl::Rotate(float degrees)
220 {
221     if (real_ == nullptr) {
222         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
223         return;
224     }
225     real_->rotate(degrees);
226 }
227 
Translate(float xAxis,float yAxis)228 void PixelMapImpl::Translate(float xAxis, float yAxis)
229 {
230     if (real_ == nullptr) {
231         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
232         return;
233     }
234     real_->translate(xAxis, yAxis);
235 }
236 
GetPixelBytesNumber()237 uint32_t PixelMapImpl::GetPixelBytesNumber()
238 {
239     if (real_ == nullptr) {
240         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
241         return 0;
242     }
243     return real_->GetByteCount();
244 }
245 
GetBytesNumberPerRow()246 uint32_t PixelMapImpl::GetBytesNumberPerRow()
247 {
248     if (real_ == nullptr) {
249         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
250         return 0;
251     }
252     return real_->GetRowBytes();
253 }
254 
GetIsEditable()255 bool PixelMapImpl::GetIsEditable()
256 {
257     if (real_ == nullptr) {
258         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
259         return false;
260     }
261     return real_->IsEditable();
262 }
263 
GetIsStrideAlignment()264 bool PixelMapImpl::GetIsStrideAlignment()
265 {
266     if (real_ == nullptr) {
267         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
268         return false;
269     }
270     bool isDMA = real_->IsStrideAlignment();
271     return isDMA;
272 }
273 
SetColorSpace(std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace)274 uint32_t PixelMapImpl::SetColorSpace(std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace)
275 {
276 #ifdef IMAGE_COLORSPACE_FLAG
277     if (real_ == nullptr || colorSpace == nullptr) {
278         return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
279     }
280     real_->InnerSetColorSpace(*colorSpace);
281     return 0;
282 #else
283     return ERR_IMAGE_SOURCE_DATA_INCOMPLETE;
284 #endif
285 }
286 
GetColorSpace()287 std::shared_ptr<OHOS::ColorManager::ColorSpace> PixelMapImpl::GetColorSpace()
288 {
289 #ifdef IMAGE_COLORSPACE_FLAG
290     if (real_ == nullptr) {
291         IMAGE_LOGE("[PixelMapImpl] real_ is nullptr!");
292         return nullptr;
293     }
294     auto colorSpace = real_->InnerGetGrColorSpacePtr();
295     return colorSpace;
296 #else
297     return nullptr;
298 #endif
299 }
300 
ApplyColorSpace(std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace)301 uint32_t PixelMapImpl::ApplyColorSpace(std::shared_ptr<OHOS::ColorManager::ColorSpace> colorSpace)
302 {
303     if (real_ == nullptr || colorSpace == nullptr) {
304         return ERR_IMAGE_READ_PIXELMAP_FAILED;
305     }
306     return real_->ApplyColorSpace(*colorSpace);
307 }
308 
309 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
GetSurfaceSize(size_t argc,Rect & region,std::string fd)310 static bool GetSurfaceSize(size_t argc, Rect& region, std::string fd)
311 {
312     if (argc == NUM_2 && (region.width <= 0 || region.height <= 0)) {
313         IMAGE_LOGE("GetSurfaceSize invalid parameter argc = %{public}zu", argc);
314         return false;
315     }
316     if (region.width <= 0 || region.height <= 0) {
317         unsigned long numberFd = 0;
318         auto res = std::from_chars(fd.c_str(), fd.c_str() + fd.size(), numberFd);
319         if (res.ec != std::errc()) {
320             IMAGE_LOGE("GetSurfaceSize invalid fd");
321             return false;
322         }
323         sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(numberFd);
324         if (surface == nullptr) {
325             return false;
326         }
327         sptr<SyncFence> fence = SyncFence::InvalidFence();
328         // a 4 * 4 idetity matrix
329         float matrix[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
330         sptr<SurfaceBuffer> surfaceBuffer = nullptr;
331         GSError ret = surface->GetLastFlushedBuffer(surfaceBuffer, fence, matrix);
332         if (ret != OHOS::GSERROR_OK || surfaceBuffer == nullptr) {
333             IMAGE_LOGE("GetLastFlushedBuffer fail, ret = %{public}d", ret);
334             return false;
335         }
336         region.width = surfaceBuffer->GetWidth();
337         region.height = surfaceBuffer->GetHeight();
338     }
339     return true;
340 }
341 #endif
342 
CreatePixelMapFromSurface(char * surfaceId,Rect region,size_t argc,uint32_t * errCode)343 std::shared_ptr<PixelMap> PixelMapImpl::CreatePixelMapFromSurface(
344     char* surfaceId, Rect region, size_t argc, uint32_t* errCode)
345 {
346 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
347     *errCode = ERR_IMAGE_PIXELMAP_CREATE_FAILED;
348     return nullptr;
349 #else
350     *errCode = argc == NUM_2 ? ERR_IMAGE_INVALID_PARAMETER : COMMON_ERR_INVALID_PARAMETER;
351     if (surfaceId == nullptr) {
352         IMAGE_LOGE("surfaceId is nullptr!");
353         return nullptr;
354     }
355     IMAGE_LOGD("CreatePixelMapFromSurface IN");
356     IMAGE_LOGD("CreatePixelMapFromSurface id:%{public}s,area:%{public}d,%{public}d,%{public}d,%{public}d", surfaceId,
357         region.left, region.top, region.height, region.width);
358     if (!std::regex_match(surfaceId, std::regex("\\d+"))) {
359         IMAGE_LOGE("CreatePixelMapFromSurface empty or invalid surfaceId");
360         return nullptr;
361     }
362     if (!GetSurfaceSize(argc, region, surfaceId)) {
363         return nullptr;
364     }
365     auto& rsClient = Rosen::RSInterfaces::GetInstance();
366     OHOS::Rect r = {
367         .x = region.left,
368         .y = region.top,
369         .w = region.width,
370         .h = region.height,
371     };
372     unsigned long newSurfaceId = 0;
373     auto res = std::from_chars(surfaceId, surfaceId + std::string(surfaceId).size(), newSurfaceId);
374     if (res.ec != std::errc()) {
375         IMAGE_LOGE("CreatePixelMapFromSurface invalid surfaceId");
376         *errCode = ERR_IMAGE_PIXELMAP_CREATE_FAILED;
377         return nullptr;
378     }
379     std::shared_ptr<PixelMap> pixelMap = rsClient.CreatePixelMapFromSurfaceId(newSurfaceId, r);
380 #ifndef EXT_PIXEL
381     if (pixelMap == nullptr) {
382         res = std::from_chars(surfaceId, surfaceId + std::string(surfaceId).size(), newSurfaceId);
383         if (res.ec != std::errc()) {
384             IMAGE_LOGE("CreatePixelMapFromSurface invalid surfaceId");
385             *errCode = ERR_IMAGE_PIXELMAP_CREATE_FAILED;
386             return nullptr;
387         }
388         pixelMap = CreatePixelMapFromSurfaceId(newSurfaceId, region);
389     }
390 #endif
391     *errCode = SUCCESS;
392     return pixelMap;
393 #endif
394 }
395 
Marshalling(int64_t rpcId)396 uint32_t PixelMapImpl::Marshalling(int64_t rpcId)
397 {
398 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
399     return ERR_IMAGE_INVALID_PARAMETER;
400 #else
401     IMAGE_LOGD("Marshalling IN");
402     if (real_ == nullptr) {
403         IMAGE_LOGE("marshalling pixel map to parcel failed.");
404         return ERR_IPC;
405     }
406     auto messageSequence = FFIData::GetData<MessageSequenceImpl>(rpcId);
407     if (!messageSequence) {
408         IMAGE_LOGE("[PixelMap] rpc not exist %{public}" PRId64, rpcId);
409         return ERR_IMAGE_INVALID_PARAMETER;
410     }
411     auto messageParcel = messageSequence->GetMessageParcel();
412     if (messageParcel == nullptr) {
413         IMAGE_LOGE("marshalling pixel map to parcel failed.");
414         return ERR_IPC;
415     }
416     bool st = real_->Marshalling(*messageParcel);
417     if (!st) {
418         IMAGE_LOGE("marshalling pixel map to parcel failed.");
419         return ERR_IPC;
420     }
421     return SUCCESS;
422 #endif
423 }
424 
Unmarshalling(int64_t rpcId,uint32_t * errCode)425 std::shared_ptr<PixelMap> PixelMapImpl::Unmarshalling(int64_t rpcId, uint32_t* errCode)
426 {
427 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
428     *errCode = ERR_IMAGE_INVALID_PARAMETER;
429     return nullptr;
430 #else
431     IMAGE_LOGD("Unmarshalling IN");
432     auto messageSequence = FFIData::GetData<MessageSequenceImpl>(rpcId);
433     if (!messageSequence) {
434         IMAGE_LOGE("[PixelMap] rpc not exist %{public}" PRId64, rpcId);
435         *errCode = ERR_IMAGE_INVALID_PARAMETER;
436         return nullptr;
437     }
438     auto messageParcel = messageSequence->GetMessageParcel();
439     if (messageParcel == nullptr) {
440         IMAGE_LOGE("UnmarshallingExec invalid parameter: messageParcel is null");
441         *errCode = ERR_IPC;
442         return nullptr;
443     }
444     PIXEL_MAP_ERR error;
445     auto pixelmap = PixelMap::Unmarshalling(*messageParcel, error);
446     if (pixelmap == nullptr) {
447         *errCode = error.errorCode;
448         return nullptr;
449     }
450     std::shared_ptr<PixelMap> pixelPtr(pixelmap);
451     return pixelPtr;
452 #endif
453 }
454 
CreatePixelMapFromParcel(int64_t rpcId,uint32_t * errCode)455 std::shared_ptr<PixelMap> PixelMapImpl::CreatePixelMapFromParcel(int64_t rpcId, uint32_t* errCode)
456 {
457 #if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
458     *errCode = ERR_IMAGE_PIXELMAP_CREATE_FAILED;
459     return nullptr;
460 #else
461     IMAGE_LOGD("CreatePixelMapFromParcel IN");
462     auto messageSequence = FFIData::GetData<MessageSequenceImpl>(rpcId);
463     if (!messageSequence) {
464         IMAGE_LOGE("[PixelMap] rpc not exist %{public}" PRId64, rpcId);
465         *errCode = ERR_IMAGE_INVALID_PARAMETER;
466         return nullptr;
467     }
468     auto messageParcel = messageSequence->GetMessageParcel();
469     if (messageParcel == nullptr) {
470         IMAGE_LOGE("get pacel failed");
471         *errCode = ERR_IPC;
472         return nullptr;
473     }
474     PIXEL_MAP_ERR error;
475     auto pixelmap = PixelMap::Unmarshalling(*messageParcel, error);
476     if (pixelmap == nullptr) {
477         *errCode = error.errorCode;
478         return nullptr;
479     }
480     std::shared_ptr<PixelMap> pixelPtr(pixelmap);
481     return pixelPtr;
482 #endif
483 }
484 
TypeFormat(PixelFormat & pixelForamt)485 static FormatType TypeFormat(PixelFormat& pixelForamt)
486 {
487     switch (pixelForamt) {
488         case PixelFormat::ARGB_8888:
489         case PixelFormat::RGB_565:
490         case PixelFormat::RGBA_8888:
491         case PixelFormat::BGRA_8888:
492         case PixelFormat::RGB_888:
493         case PixelFormat::RGBA_F16:
494         case PixelFormat::RGBA_1010102: {
495             return FormatType::RGB;
496         }
497         case PixelFormat::NV21:
498         case PixelFormat::NV12:
499         case PixelFormat::YCBCR_P010:
500         case PixelFormat::YCRCB_P010: {
501             return FormatType::YUV;
502         }
503         case PixelFormat::ASTC_4x4: {
504             return FormatType::ASTC;
505         }
506         default:
507             return FormatType::UNKNOWN;
508     }
509 }
510 
ConvertPixelMapFormat(PixelFormat destFormat)511 uint32_t PixelMapImpl::ConvertPixelMapFormat(PixelFormat destFormat)
512 {
513     if (real_ == nullptr) {
514         IMAGE_LOGE("pixelmap is nullptr");
515         return ERR_IMAGE_PIXELMAP_CREATE_FAILED;
516     }
517     if (TypeFormat(destFormat) == FormatType::UNKNOWN) {
518         IMAGE_LOGE("dstFormat is not support or invalid");
519         return ERR_IMAGE_INVALID_PARAMETER;
520     }
521     FormatType srcFormatType = FormatType::UNKNOWN;
522     if (real_->GetPixelFormat() == PixelFormat::ASTC_4x4) {
523         srcFormatType = FormatType::ASTC;
524     }
525     FormatType dstFormatType = TypeFormat(destFormat);
526     uint32_t result = SUCCESS;
527     if (dstFormatType == FormatType::YUV &&
528         (srcFormatType == FormatType::UNKNOWN || srcFormatType == FormatType::RGB)) {
529         result = ImageFormatConvert::ConvertImageFormat(real_, destFormat);
530     } else if ((dstFormatType == FormatType::RGB) &&
531                (srcFormatType == FormatType::UNKNOWN || srcFormatType == FormatType::YUV)) {
532         result = ImageFormatConvert::ConvertImageFormat(real_, destFormat);
533     } else if ((dstFormatType == FormatType::RGB) && (srcFormatType == FormatType::ASTC)) {
534         result = ImageFormatConvert::ConvertImageFormat(real_, destFormat);
535     }
536     if (result == SUCCESS) {
537         ImageUtils::FlushSurfaceBuffer(const_cast<PixelMap*>(real_.get()));
538     }
539     return result;
540 }
541 } // namespace Media
542 } // namespace OHOS