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