1 /*
2 * Copyright (c) 2021-2022 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_ohos.h"
17
18 #include "drawable_descriptor.h"
19 #include "media_errors.h"
20 #include "pixel_map_manager.h"
21
22 #include "core/image/image_file_cache.h"
23
24 namespace OHOS::Ace {
25
PixelFormatConverter(Media::PixelFormat pixelFormat)26 PixelFormat PixelMapOhos::PixelFormatConverter(Media::PixelFormat pixelFormat)
27 {
28 switch (pixelFormat) {
29 case Media::PixelFormat::RGB_565:
30 return PixelFormat::RGB_565;
31 case Media::PixelFormat::RGBA_8888:
32 return PixelFormat::RGBA_8888;
33 case Media::PixelFormat::RGBA_1010102:
34 return PixelFormat::RGBA_1010102;
35 case Media::PixelFormat::BGRA_8888:
36 return PixelFormat::BGRA_8888;
37 case Media::PixelFormat::ALPHA_8:
38 return PixelFormat::ALPHA_8;
39 case Media::PixelFormat::RGBA_F16:
40 return PixelFormat::RGBA_F16;
41 case Media::PixelFormat::UNKNOWN:
42 return PixelFormat::UNKNOWN;
43 case Media::PixelFormat::ARGB_8888:
44 return PixelFormat::ARGB_8888;
45 case Media::PixelFormat::RGB_888:
46 return PixelFormat::RGB_888;
47 case Media::PixelFormat::NV21:
48 return PixelFormat::NV21;
49 case Media::PixelFormat::NV12:
50 return PixelFormat::NV12;
51 case Media::PixelFormat::CMYK:
52 return PixelFormat::CMYK;
53 default:
54 return PixelFormat::UNKNOWN;
55 }
56 }
57
ConvertToMediaPixelFormat(Ace::PixelFormat pixelFormat)58 Media::PixelFormat PixelMapOhos::ConvertToMediaPixelFormat(Ace::PixelFormat pixelFormat)
59 {
60 switch (pixelFormat) {
61 case PixelFormat::RGB_565:
62 return Media::PixelFormat::RGB_565;
63 case PixelFormat::RGBA_8888:
64 return Media::PixelFormat::RGBA_8888;
65 case PixelFormat::RGBA_1010102:
66 return Media::PixelFormat::RGBA_1010102;
67 case PixelFormat::BGRA_8888:
68 return Media::PixelFormat::BGRA_8888;
69 case PixelFormat::ALPHA_8:
70 return Media::PixelFormat::ALPHA_8;
71 case PixelFormat::RGBA_F16:
72 return Media::PixelFormat::RGBA_F16;
73 case PixelFormat::UNKNOWN:
74 return Media::PixelFormat::UNKNOWN;
75 case PixelFormat::ARGB_8888:
76 return Media::PixelFormat::ARGB_8888;
77 case PixelFormat::RGB_888:
78 return Media::PixelFormat::RGB_888;
79 case PixelFormat::NV21:
80 return Media::PixelFormat::NV21;
81 case PixelFormat::NV12:
82 return Media::PixelFormat::NV12;
83 case PixelFormat::CMYK:
84 return Media::PixelFormat::CMYK;
85 default:
86 return Media::PixelFormat::UNKNOWN;
87 }
88 }
89
AlphaTypeConverter(Media::AlphaType alphaType)90 AlphaType PixelMapOhos::AlphaTypeConverter(Media::AlphaType alphaType)
91 {
92 switch (alphaType) {
93 case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
94 return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
95 case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
96 return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
97 case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
98 return AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
99 case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
100 return AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
101 default:
102 return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
103 }
104 }
105
ConvertToMediaAlphaType(Ace::AlphaType alphaType)106 Media::AlphaType PixelMapOhos::ConvertToMediaAlphaType(Ace::AlphaType alphaType)
107 {
108 switch (alphaType) {
109 case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
110 return Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
111 case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
112 return Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
113 case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
114 return Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
115 case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
116 return Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
117 default:
118 return Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
119 }
120 }
121
AllocatorTypeConverter(Media::AllocatorType allocatorType)122 AllocatorType PixelMapOhos::AllocatorTypeConverter(Media::AllocatorType allocatorType)
123 {
124 switch (allocatorType) {
125 case Media::AllocatorType::DEFAULT:
126 return AllocatorType::DEFAULT;
127 case Media::AllocatorType::HEAP_ALLOC:
128 return AllocatorType::HEAP_ALLOC;
129 case Media::AllocatorType::SHARE_MEM_ALLOC:
130 return AllocatorType::SHARE_MEM_ALLOC;
131 case Media::AllocatorType::CUSTOM_ALLOC:
132 return AllocatorType::CUSTOM_ALLOC;
133 case Media::AllocatorType::DMA_ALLOC:
134 return AllocatorType::DMA_ALLOC;
135 default:
136 return AllocatorType::DEFAULT;
137 }
138 }
139
ConvertToMediaScaleMode(Ace::ScaleMode scaleMode)140 Media::ScaleMode PixelMapOhos::ConvertToMediaScaleMode(Ace::ScaleMode scaleMode)
141 {
142 switch (scaleMode) {
143 case ScaleMode::CENTER_CROP:
144 return Media::ScaleMode::CENTER_CROP;
145 case ScaleMode::FIT_TARGET_SIZE:
146 return Media::ScaleMode::FIT_TARGET_SIZE;
147 default:
148 return Media::ScaleMode::FIT_TARGET_SIZE;
149 }
150 }
151
Create(std::unique_ptr<Media::PixelMap> && pixmap)152 RefPtr<PixelMap> PixelMap::Create(std::unique_ptr<Media::PixelMap>&& pixmap)
153 {
154 return AceType::MakeRefPtr<PixelMapOhos>(std::move(pixmap));
155 }
156
Create(const InitializationOptions & opts)157 RefPtr<PixelMap> PixelMap::Create(const InitializationOptions& opts)
158 {
159 Media::InitializationOptions options;
160 opts.size.Width();
161 options.size.width = opts.size.Width();
162 options.size.height = opts.size.Height();
163 options.srcPixelFormat = PixelMapOhos::ConvertToMediaPixelFormat(opts.srcPixelFormat);
164 options.pixelFormat = PixelMapOhos::ConvertToMediaPixelFormat(opts.pixelFormat);
165 options.editable = opts.editable;
166 options.alphaType = PixelMapOhos::ConvertToMediaAlphaType(opts.alphaType);
167 options.scaleMode = PixelMapOhos::ConvertToMediaScaleMode(opts.scaleMode);
168 options.srcRowStride = opts.srcRowStride;
169 options.useSourceIfMatch = opts.useSourceIfMatch;
170 options.useDMA = opts.useDMA;
171 std::unique_ptr<Media::PixelMap> pixmap = Media::PixelMap::Create(options);
172 return AceType::MakeRefPtr<PixelMapOhos>(std::move(pixmap));
173 }
174
175 #if defined(ACE_STATIC)
176 // only for 1.2
Create(const std::shared_ptr<Media::PixelMap> & pixmap)177 RefPtr<PixelMap> PixelMap::Create(const std::shared_ptr<Media::PixelMap>& pixmap)
178 {
179 return AceType::MakeRefPtr<PixelMapOhos>(pixmap);
180 }
181 #endif
182
CreatePixelMap(void * rawPtr)183 RefPtr<PixelMap> PixelMap::CreatePixelMap(void* rawPtr)
184 {
185 auto* pixmapPtr = reinterpret_cast<std::shared_ptr<Media::PixelMap>*>(rawPtr);
186 if (pixmapPtr == nullptr || *pixmapPtr == nullptr) {
187 TAG_LOGW(AceLogTag::ACE_IMAGE, "invalid pixmap");
188 return nullptr;
189 }
190 return AceType::MakeRefPtr<PixelMapOhos>(*pixmapPtr);
191 }
192
CopyPixelMap(const RefPtr<PixelMap> & pixelMap)193 RefPtr<PixelMap> PixelMap::CopyPixelMap(const RefPtr<PixelMap>& pixelMap)
194 {
195 CHECK_NULL_RETURN(pixelMap, nullptr);
196 OHOS::Media::InitializationOptions opts;
197 auto mediaPixelMap = pixelMap->GetPixelMapSharedPtr();
198 std::unique_ptr<Media::PixelMap> uniquePixelMap = Media::PixelMap::Create(*mediaPixelMap, opts);
199 CHECK_NULL_RETURN(uniquePixelMap, nullptr);
200 Media::PixelMap* pixelMapRelease = uniquePixelMap.release();
201 CHECK_NULL_RETURN(pixelMapRelease, nullptr);
202 std::shared_ptr<Media::PixelMap> newPixelMap(pixelMapRelease);
203 CHECK_NULL_RETURN(newPixelMap, nullptr);
204 return AceType::MakeRefPtr<PixelMapOhos>(newPixelMap);
205 }
206
DecodeTlv(std::vector<uint8_t> & buff)207 RefPtr<PixelMap> PixelMap::DecodeTlv(std::vector<uint8_t>& buff)
208 {
209 Media::PixelMap* pixelMapRelease = OHOS::Media::PixelMap::DecodeTlv(buff);
210 CHECK_NULL_RETURN(pixelMapRelease, nullptr);
211 std::shared_ptr<Media::PixelMap> newPixelMap(pixelMapRelease);
212 CHECK_NULL_RETURN(newPixelMap, nullptr);
213 return AceType::MakeRefPtr<PixelMapOhos>(newPixelMap);
214 }
215
EncodeTlv(std::vector<uint8_t> & buff)216 bool PixelMapOhos::EncodeTlv(std::vector<uint8_t>& buff)
217 {
218 CHECK_NULL_RETURN(pixmap_, false);
219 return pixmap_->EncodeTlv(buff);
220 }
221
GetFromDrawable(void * ptr)222 RefPtr<PixelMap> PixelMap::GetFromDrawable(void* ptr)
223 {
224 CHECK_NULL_RETURN(ptr, nullptr);
225 auto* drawable = reinterpret_cast<Napi::DrawableDescriptor*>(ptr);
226 return AceType::MakeRefPtr<PixelMapOhos>(drawable->GetPixelMap());
227 }
228
GetPxielMapListFromAnimatedDrawable(void * ptr,std::vector<RefPtr<PixelMap>> & pixelMaps,int32_t & duration,int32_t & iterations)229 bool PixelMap::GetPxielMapListFromAnimatedDrawable(void* ptr, std::vector<RefPtr<PixelMap>>& pixelMaps,
230 int32_t& duration, int32_t& iterations)
231 {
232 CHECK_NULL_RETURN(ptr, false);
233 auto* drawable = reinterpret_cast<Napi::DrawableDescriptor*>(ptr);
234 auto drawableType = drawable->GetDrawableType();
235 if (drawableType != Napi::DrawableDescriptor::DrawableType::ANIMATED) {
236 return false;
237 }
238 auto* animatedDrawable = static_cast<Napi::AnimatedDrawableDescriptor*>(drawable);
239 std::vector<std::shared_ptr<Media::PixelMap>> pixelMapList = animatedDrawable->GetPixelMapList();
240 for (uint32_t i = 0; i < pixelMapList.size(); i++) {
241 pixelMaps.push_back(AceType::MakeRefPtr<PixelMapOhos>(std::move(pixelMapList[i])));
242 }
243 duration = animatedDrawable->GetDuration();
244 iterations = animatedDrawable->GetIterations();
245 return true;
246 }
247
CreatePixelMapFromDataAbility(void * ptr)248 RefPtr<PixelMap> PixelMap::CreatePixelMapFromDataAbility(void* ptr)
249 {
250 auto* pixmap = reinterpret_cast<Media::PixelMap*>(ptr);
251 CHECK_NULL_RETURN(pixmap, nullptr);
252 return AceType::MakeRefPtr<PixelMapOhos>(std::shared_ptr<Media::PixelMap>(pixmap));
253 }
254
GetWidth() const255 int32_t PixelMapOhos::GetWidth() const
256 {
257 CHECK_NULL_RETURN(pixmap_, 0);
258 return pixmap_->GetWidth();
259 }
260
GetHeight() const261 int32_t PixelMapOhos::GetHeight() const
262 {
263 CHECK_NULL_RETURN(pixmap_, 0);
264 return pixmap_->GetHeight();
265 }
266
GetPixels() const267 const uint8_t* PixelMapOhos::GetPixels() const
268 {
269 CHECK_NULL_RETURN(pixmap_, nullptr);
270 return pixmap_->GetPixels();
271 }
272
GetPixelFormat() const273 PixelFormat PixelMapOhos::GetPixelFormat() const
274 {
275 CHECK_NULL_RETURN(pixmap_, PixelFormat::UNKNOWN);
276 return PixelFormatConverter(pixmap_->GetPixelFormat());
277 }
278
GetAlphaType() const279 AlphaType PixelMapOhos::GetAlphaType() const
280 {
281 CHECK_NULL_RETURN(pixmap_, AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN);
282 return AlphaTypeConverter(pixmap_->GetAlphaType());
283 }
284
GetRowStride() const285 int32_t PixelMapOhos::GetRowStride() const
286 {
287 CHECK_NULL_RETURN(pixmap_, 0);
288 return pixmap_->GetRowStride();
289 }
290
GetRowBytes() const291 int32_t PixelMapOhos::GetRowBytes() const
292 {
293 CHECK_NULL_RETURN(pixmap_, 0);
294 return pixmap_->GetRowBytes();
295 }
296
GetByteCount() const297 int32_t PixelMapOhos::GetByteCount() const
298 {
299 CHECK_NULL_RETURN(pixmap_, 0);
300 return pixmap_->GetByteCount();
301 }
302
GetAllocatorType() const303 AllocatorType PixelMapOhos::GetAllocatorType() const
304 {
305 CHECK_NULL_RETURN(pixmap_, AllocatorType::DEFAULT);
306 return AllocatorTypeConverter(pixmap_->GetAllocatorType());
307 }
308
IsHdr() const309 bool PixelMapOhos::IsHdr() const
310 {
311 CHECK_NULL_RETURN(pixmap_, false);
312 return pixmap_->IsHdr();
313 }
314
GetPixelManager() const315 void* PixelMapOhos::GetPixelManager() const
316 {
317 Media::InitializationOptions opts;
318 CHECK_NULL_RETURN(pixmap_, nullptr);
319 auto newPixelMap = Media::PixelMap::Create(*pixmap_, opts);
320 return reinterpret_cast<void*>(new Media::PixelMapManager(newPixelMap.release()));
321 }
322
GetRawPixelMapPtr() const323 void* PixelMapOhos::GetRawPixelMapPtr() const
324 {
325 CHECK_NULL_RETURN(pixmap_, nullptr);
326 return pixmap_.get();
327 }
328
Scale(float xAxis,float yAxis)329 void PixelMapOhos::Scale(float xAxis, float yAxis)
330 {
331 CHECK_NULL_VOID(pixmap_);
332 pixmap_->scale(xAxis, yAxis);
333 }
334
Scale(float xAxis,float yAxis,const AceAntiAliasingOption & option)335 void PixelMapOhos::Scale(float xAxis, float yAxis, const AceAntiAliasingOption &option)
336 {
337 CHECK_NULL_VOID(pixmap_);
338 switch (option) {
339 case AceAntiAliasingOption::NONE:
340 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::NONE);
341 break;
342 case AceAntiAliasingOption::LOW:
343 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
344 break;
345 case AceAntiAliasingOption::MEDIUM:
346 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::MEDIUM);
347 break;
348 case AceAntiAliasingOption::HIGH:
349 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::HIGH);
350 break;
351 default:
352 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::NONE);
353 break;
354 }
355 }
356
GetId()357 std::string PixelMapOhos::GetId()
358 {
359 // using pixmap addr
360 CHECK_NULL_RETURN(pixmap_, "nullptr");
361 std::stringstream strm;
362 strm << pixmap_.get();
363 return strm.str();
364 }
365
GetModifyId()366 std::string PixelMapOhos::GetModifyId()
367 {
368 return {};
369 }
370
GetPixelMapSharedPtr()371 std::shared_ptr<Media::PixelMap> PixelMapOhos::GetPixelMapSharedPtr()
372 {
373 return pixmap_;
374 }
375
GetWritablePixels() const376 void* PixelMapOhos::GetWritablePixels() const
377 {
378 CHECK_NULL_RETURN(pixmap_, nullptr);
379 return pixmap_->GetWritablePixels();
380 }
381
GetPixelsVec(std::vector<uint8_t> & data) const382 bool PixelMapOhos::GetPixelsVec(std::vector<uint8_t>& data) const
383 {
384 CHECK_NULL_RETURN(pixmap_, false);
385 data.resize(pixmap_->GetByteCount());
386 uint8_t* dst = data.data();
387 uint32_t errCode = pixmap_->ReadPixels(pixmap_->GetByteCount(), dst);
388 if (errCode) {
389 TAG_LOGW(AceLogTag::ACE_IMAGE, "GetPixelsVec error, errCode=%{public}d", errCode);
390 return false;
391 }
392 return true;
393 }
394
ConvertSkImageToPixmap(const uint32_t * colors,uint32_t colorLength,int32_t width,int32_t height)395 RefPtr<PixelMap> PixelMap::ConvertSkImageToPixmap(
396 const uint32_t* colors, uint32_t colorLength, int32_t width, int32_t height)
397 {
398 Media::InitializationOptions opts;
399 opts.size.width = width;
400 opts.size.height = height;
401 opts.editable = true;
402 std::unique_ptr<Media::PixelMap> pixmap = Media::PixelMap::Create(colors, colorLength, opts);
403 CHECK_NULL_RETURN(pixmap, nullptr);
404 std::shared_ptr<Media::PixelMap> sharedPixelmap(pixmap.release());
405 return AceType::MakeRefPtr<PixelMapOhos>(sharedPixelmap);
406 }
407
SavePixelMapToFile(const std::string & dst) const408 void PixelMapOhos::SavePixelMapToFile(const std::string& dst) const
409 {
410 int32_t w = pixmap_->GetWidth();
411 int32_t h = pixmap_->GetHeight();
412 int32_t totalSize = static_cast<int32_t>(pixmap_->GetCapacity());
413 auto rowStride = pixmap_->GetRowStride();
414 uint64_t nowTime = static_cast<uint64_t>(
415 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
416 .count());
417 std::string filename = std::to_string(nowTime) + "_w" + std::to_string(w) + "_h" + std::to_string(h) +
418 "_rowStride" + std::to_string(rowStride) + "_byteCount" + std::to_string(totalSize) + dst +
419 ".dat";
420 auto path = ImageFileCache::GetInstance().ConstructCacheFilePath(filename);
421 std::ofstream outFile(path, std::fstream::out);
422 if (!outFile.is_open()) {
423 TAG_LOGW(AceLogTag::ACE_IMAGE, "write error, path=%{public}s", path.c_str());
424 }
425 outFile.write(reinterpret_cast<const char*>(pixmap_->GetPixels()), totalSize);
426 TAG_LOGI(AceLogTag::ACE_IMAGE, "write success, path=%{public}s", path.c_str());
427 }
428
GetCropPixelMap(const Rect & srcRect)429 RefPtr<PixelMap> PixelMapOhos::GetCropPixelMap(const Rect& srcRect)
430 {
431 Media::InitializationOptions options;
432 options.size.width = static_cast<int32_t>(srcRect.Width());
433 options.size.height = static_cast<int32_t>(srcRect.Height());
434 options.pixelFormat = Media::PixelFormat::RGBA_8888;
435 options.alphaType = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
436 options.scaleMode = Media::ScaleMode::FIT_TARGET_SIZE;
437
438 Media::Rect rect {static_cast<int32_t>(srcRect.Left()), static_cast<int32_t>(srcRect.Top()),
439 static_cast<int32_t>(srcRect.Width()), static_cast<int32_t>(srcRect.Height()) };
440 auto resPixelmap = OHOS::Media::PixelMap::Create(*pixmap_, rect, options);
441 return AceType::MakeRefPtr<PixelMapOhos>(std::move(resPixelmap));
442 }
443
WritePixels(const WritePixelsOptions & opts)444 uint32_t PixelMapOhos::WritePixels(const WritePixelsOptions& opts)
445 {
446 CHECK_NULL_RETURN(pixmap_, Media::ERR_IMAGE_WRITE_PIXELMAP_FAILED);
447 Media::Rect rect { static_cast<int32_t>(opts.region.Left()), static_cast<int32_t>(opts.region.Top()),
448 static_cast<int32_t>(opts.region.Width()), static_cast<int32_t>(opts.region.Height()) };
449 Media::RWPixelsOptions options;
450 options.pixels = opts.source;
451 options.bufferSize = opts.bufferSize;
452 options.offset = opts.offset;
453 options.stride = opts.stride;
454 options.region = rect;
455 options.pixelFormat = PixelMapOhos::ConvertToMediaPixelFormat(opts.srcPixelFormat);
456 return pixmap_->WritePixels(options);
457 }
458
GetInnerColorGamut() const459 uint32_t PixelMapOhos::GetInnerColorGamut() const
460 {
461 #ifdef IMAGE_COLORSPACE_FLAG
462 if (!pixmap_) {
463 TAG_LOGI(AceLogTag::ACE_IMAGE, "pixmap_ is nullptr");
464 return ColorManager::ColorSpaceName::NONE;
465 }
466 #else
467 return pixmap_->InnerGetGrColorSpace().GetColorSpaceName();
468 #endif
469 return 0;
470 }
471
SetMemoryName(std::string pixelMapName) const472 void PixelMapOhos::SetMemoryName(std::string pixelMapName) const
473 {
474 CHECK_NULL_VOID(pixmap_);
475 LOGD("PixelMapOhos::SetMemoryName, %{public}s", pixelMapName.c_str());
476 pixmap_->SetMemoryName(pixelMapName);
477 }
478 } // namespace OHOS::Ace
479