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
CreatePixelMap(void * rawPtr)175 RefPtr<PixelMap> PixelMap::CreatePixelMap(void* rawPtr)
176 {
177 auto* pixmapPtr = reinterpret_cast<std::shared_ptr<Media::PixelMap>*>(rawPtr);
178 if (pixmapPtr == nullptr || *pixmapPtr == nullptr) {
179 TAG_LOGW(AceLogTag::ACE_IMAGE, "pixmap pointer is nullptr when CreatePixelMap.");
180 return nullptr;
181 }
182 return AceType::MakeRefPtr<PixelMapOhos>(*pixmapPtr);
183 }
184
CopyPixelMap(const RefPtr<PixelMap> & pixelMap)185 RefPtr<PixelMap> PixelMap::CopyPixelMap(const RefPtr<PixelMap>& pixelMap)
186 {
187 CHECK_NULL_RETURN(pixelMap, nullptr);
188 OHOS::Media::InitializationOptions opts;
189 auto mediaPixelMap = pixelMap->GetPixelMapSharedPtr();
190 std::unique_ptr<Media::PixelMap> uniquePixelMap = Media::PixelMap::Create(*mediaPixelMap, opts);
191 CHECK_NULL_RETURN(uniquePixelMap, nullptr);
192 Media::PixelMap* pixelMapRelease = uniquePixelMap.release();
193 CHECK_NULL_RETURN(pixelMapRelease, nullptr);
194 std::shared_ptr<Media::PixelMap> newPixelMap(pixelMapRelease);
195 CHECK_NULL_RETURN(newPixelMap, nullptr);
196 return AceType::MakeRefPtr<PixelMapOhos>(newPixelMap);
197 }
198
DecodeTlv(std::vector<uint8_t> & buff)199 RefPtr<PixelMap> PixelMap::DecodeTlv(std::vector<uint8_t>& buff)
200 {
201 Media::PixelMap* pixelMapRelease = OHOS::Media::PixelMap::DecodeTlv(buff);
202 CHECK_NULL_RETURN(pixelMapRelease, nullptr);
203 std::shared_ptr<Media::PixelMap> newPixelMap(pixelMapRelease);
204 CHECK_NULL_RETURN(newPixelMap, nullptr);
205 return AceType::MakeRefPtr<PixelMapOhos>(newPixelMap);
206 }
207
EncodeTlv(std::vector<uint8_t> & buff)208 bool PixelMapOhos::EncodeTlv(std::vector<uint8_t>& buff)
209 {
210 CHECK_NULL_RETURN(pixmap_, false);
211 return pixmap_->EncodeTlv(buff);
212 }
213
GetFromDrawable(void * ptr)214 RefPtr<PixelMap> PixelMap::GetFromDrawable(void* ptr)
215 {
216 CHECK_NULL_RETURN(ptr, nullptr);
217 auto* drawable = reinterpret_cast<Napi::DrawableDescriptor*>(ptr);
218 return AceType::MakeRefPtr<PixelMapOhos>(drawable->GetPixelMap());
219 }
220
GetPxielMapListFromAnimatedDrawable(void * ptr,std::vector<RefPtr<PixelMap>> & pixelMaps,int32_t & duration,int32_t & iterations)221 bool PixelMap::GetPxielMapListFromAnimatedDrawable(void* ptr, std::vector<RefPtr<PixelMap>>& pixelMaps,
222 int32_t& duration, int32_t& iterations)
223 {
224 CHECK_NULL_RETURN(ptr, false);
225 auto* drawable = reinterpret_cast<Napi::DrawableDescriptor*>(ptr);
226 auto drawableType = drawable->GetDrawableType();
227 if (drawableType != Napi::DrawableDescriptor::DrawableType::ANIMATED) {
228 return false;
229 }
230 auto* animatedDrawable = static_cast<Napi::AnimatedDrawableDescriptor*>(drawable);
231 std::vector<std::shared_ptr<Media::PixelMap>> pixelMapList = animatedDrawable->GetPixelMapList();
232 for (uint32_t i = 0; i < pixelMapList.size(); i++) {
233 pixelMaps.push_back(AceType::MakeRefPtr<PixelMapOhos>(std::move(pixelMapList[i])));
234 }
235 duration = animatedDrawable->GetDuration();
236 iterations = animatedDrawable->GetIterations();
237 return true;
238 }
239
CreatePixelMapFromDataAbility(void * ptr)240 RefPtr<PixelMap> PixelMap::CreatePixelMapFromDataAbility(void* ptr)
241 {
242 auto* pixmap = reinterpret_cast<Media::PixelMap*>(ptr);
243 CHECK_NULL_RETURN(pixmap, nullptr);
244 return AceType::MakeRefPtr<PixelMapOhos>(std::shared_ptr<Media::PixelMap>(pixmap));
245 }
246
GetWidth() const247 int32_t PixelMapOhos::GetWidth() const
248 {
249 CHECK_NULL_RETURN(pixmap_, 0);
250 return pixmap_->GetWidth();
251 }
252
GetHeight() const253 int32_t PixelMapOhos::GetHeight() const
254 {
255 CHECK_NULL_RETURN(pixmap_, 0);
256 return pixmap_->GetHeight();
257 }
258
GetPixels() const259 const uint8_t* PixelMapOhos::GetPixels() const
260 {
261 CHECK_NULL_RETURN(pixmap_, nullptr);
262 return pixmap_->GetPixels();
263 }
264
GetPixelFormat() const265 PixelFormat PixelMapOhos::GetPixelFormat() const
266 {
267 CHECK_NULL_RETURN(pixmap_, PixelFormat::UNKNOWN);
268 return PixelFormatConverter(pixmap_->GetPixelFormat());
269 }
270
GetAlphaType() const271 AlphaType PixelMapOhos::GetAlphaType() const
272 {
273 CHECK_NULL_RETURN(pixmap_, AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN);
274 return AlphaTypeConverter(pixmap_->GetAlphaType());
275 }
276
GetRowStride() const277 int32_t PixelMapOhos::GetRowStride() const
278 {
279 CHECK_NULL_RETURN(pixmap_, 0);
280 return pixmap_->GetRowStride();
281 }
282
GetRowBytes() const283 int32_t PixelMapOhos::GetRowBytes() const
284 {
285 CHECK_NULL_RETURN(pixmap_, 0);
286 return pixmap_->GetRowBytes();
287 }
288
GetByteCount() const289 int32_t PixelMapOhos::GetByteCount() const
290 {
291 CHECK_NULL_RETURN(pixmap_, 0);
292 return pixmap_->GetByteCount();
293 }
294
GetAllocatorType() const295 AllocatorType PixelMapOhos::GetAllocatorType() const
296 {
297 CHECK_NULL_RETURN(pixmap_, AllocatorType::DEFAULT);
298 return AllocatorTypeConverter(pixmap_->GetAllocatorType());
299 }
300
IsHdr() const301 bool PixelMapOhos::IsHdr() const
302 {
303 CHECK_NULL_RETURN(pixmap_, false);
304 return pixmap_->IsHdr();
305 }
306
GetPixelManager() const307 void* PixelMapOhos::GetPixelManager() const
308 {
309 Media::InitializationOptions opts;
310 CHECK_NULL_RETURN(pixmap_, nullptr);
311 auto newPixelMap = Media::PixelMap::Create(*pixmap_, opts);
312 return reinterpret_cast<void*>(new Media::PixelMapManager(newPixelMap.release()));
313 }
314
GetRawPixelMapPtr() const315 void* PixelMapOhos::GetRawPixelMapPtr() const
316 {
317 CHECK_NULL_RETURN(pixmap_, nullptr);
318 return pixmap_.get();
319 }
320
Scale(float xAxis,float yAxis)321 void PixelMapOhos::Scale(float xAxis, float yAxis)
322 {
323 CHECK_NULL_VOID(pixmap_);
324 pixmap_->scale(xAxis, yAxis);
325 }
326
Scale(float xAxis,float yAxis,const AceAntiAliasingOption & option)327 void PixelMapOhos::Scale(float xAxis, float yAxis, const AceAntiAliasingOption &option)
328 {
329 CHECK_NULL_VOID(pixmap_);
330 switch (option) {
331 case AceAntiAliasingOption::NONE:
332 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::NONE);
333 break;
334 case AceAntiAliasingOption::LOW:
335 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
336 break;
337 case AceAntiAliasingOption::MEDIUM:
338 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::MEDIUM);
339 break;
340 case AceAntiAliasingOption::HIGH:
341 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::HIGH);
342 break;
343 default:
344 pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::NONE);
345 break;
346 }
347 }
348
GetId()349 std::string PixelMapOhos::GetId()
350 {
351 // using pixmap addr
352 CHECK_NULL_RETURN(pixmap_, "nullptr");
353 std::stringstream strm;
354 strm << pixmap_.get();
355 return strm.str();
356 }
357
GetModifyId()358 std::string PixelMapOhos::GetModifyId()
359 {
360 return {};
361 }
362
GetPixelMapSharedPtr()363 std::shared_ptr<Media::PixelMap> PixelMapOhos::GetPixelMapSharedPtr()
364 {
365 return pixmap_;
366 }
367
GetWritablePixels() const368 void* PixelMapOhos::GetWritablePixels() const
369 {
370 CHECK_NULL_RETURN(pixmap_, nullptr);
371 return pixmap_->GetWritablePixels();
372 }
373
GetPixelsVec(std::vector<uint8_t> & data) const374 bool PixelMapOhos::GetPixelsVec(std::vector<uint8_t>& data) const
375 {
376 CHECK_NULL_RETURN(pixmap_, false);
377 data.resize(pixmap_->GetByteCount());
378 uint8_t* dst = data.data();
379 uint32_t errCode = pixmap_->ReadPixels(pixmap_->GetByteCount(), dst);
380 if (errCode) {
381 TAG_LOGW(AceLogTag::ACE_IMAGE, "GetPixelsVec error, errCode=%{public}d", errCode);
382 return false;
383 }
384 return true;
385 }
386
ConvertSkImageToPixmap(const uint32_t * colors,uint32_t colorLength,int32_t width,int32_t height)387 RefPtr<PixelMap> PixelMap::ConvertSkImageToPixmap(
388 const uint32_t* colors, uint32_t colorLength, int32_t width, int32_t height)
389 {
390 Media::InitializationOptions opts;
391 opts.size.width = width;
392 opts.size.height = height;
393 opts.editable = true;
394 std::unique_ptr<Media::PixelMap> pixmap = Media::PixelMap::Create(colors, colorLength, opts);
395 CHECK_NULL_RETURN(pixmap, nullptr);
396 std::shared_ptr<Media::PixelMap> sharedPixelmap(pixmap.release());
397 return AceType::MakeRefPtr<PixelMapOhos>(sharedPixelmap);
398 }
399
SavePixelMapToFile(const std::string & dst) const400 void PixelMapOhos::SavePixelMapToFile(const std::string& dst) const
401 {
402 int32_t w = pixmap_->GetWidth();
403 int32_t h = pixmap_->GetHeight();
404 int32_t totalSize = static_cast<int32_t>(pixmap_->GetCapacity());
405 auto rowStride = pixmap_->GetRowStride();
406 uint64_t nowTime = static_cast<uint64_t>(
407 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
408 .count());
409 std::string filename = std::to_string(nowTime) + "_w" + std::to_string(w) + "_h" + std::to_string(h) +
410 "_rowStride" + std::to_string(rowStride) + "_byteCount" + std::to_string(totalSize) + dst +
411 ".dat";
412 auto path = ImageFileCache::GetInstance().ConstructCacheFilePath(filename);
413 std::ofstream outFile(path, std::fstream::out);
414 if (!outFile.is_open()) {
415 TAG_LOGW(AceLogTag::ACE_IMAGE, "write error, path=%{public}s", path.c_str());
416 }
417 outFile.write(reinterpret_cast<const char*>(pixmap_->GetPixels()), totalSize);
418 TAG_LOGI(AceLogTag::ACE_IMAGE, "write success, path=%{public}s", path.c_str());
419 }
420
GetCropPixelMap(const Rect & srcRect)421 RefPtr<PixelMap> PixelMapOhos::GetCropPixelMap(const Rect& srcRect)
422 {
423 Media::InitializationOptions options;
424 options.size.width = static_cast<int32_t>(srcRect.Width());
425 options.size.height = static_cast<int32_t>(srcRect.Height());
426 options.pixelFormat = Media::PixelFormat::RGBA_8888;
427 options.alphaType = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
428 options.scaleMode = Media::ScaleMode::FIT_TARGET_SIZE;
429
430 Media::Rect rect {srcRect.Left(), srcRect.Top(), srcRect.Width(), srcRect.Height()};
431 auto resPixelmap = OHOS::Media::PixelMap::Create(*pixmap_, rect, options);
432 return AceType::MakeRefPtr<PixelMapOhos>(std::move(resPixelmap));
433 }
434
WritePixels(const WritePixelsOptions & opts)435 uint32_t PixelMapOhos::WritePixels(const WritePixelsOptions& opts)
436 {
437 CHECK_NULL_RETURN(pixmap_, Media::ERR_IMAGE_WRITE_PIXELMAP_FAILED);
438 Media::Rect rect { opts.region.Left(), opts.region.Top(), opts.region.Width(), opts.region.Height() };
439 Media::WritePixelsOptions options;
440 options.source = opts.source;
441 options.bufferSize = opts.bufferSize;
442 options.offset = opts.offset;
443 options.stride = opts.stride;
444 options.region = rect;
445 options.srcPixelFormat = PixelMapOhos::ConvertToMediaPixelFormat(opts.srcPixelFormat);
446 return pixmap_->WritePixels(options);
447 }
448
449 } // namespace OHOS::Ace
450