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 <sstream>
19 
20 #include "drawable_descriptor.h"
21 #include "pixel_map_manager.h"
22 
23 #include "base/log/log_wrapper.h"
24 #include "base/utils/utils.h"
25 #include "core/image/image_file_cache.h"
26 
27 namespace OHOS::Ace {
28 
PixelFormatConverter(Media::PixelFormat pixelFormat)29 PixelFormat PixelMapOhos::PixelFormatConverter(Media::PixelFormat pixelFormat)
30 {
31     switch (pixelFormat) {
32         case Media::PixelFormat::RGB_565:
33             return PixelFormat::RGB_565;
34         case Media::PixelFormat::RGBA_8888:
35             return PixelFormat::RGBA_8888;
36         case Media::PixelFormat::RGBA_1010102:
37             return PixelFormat::RGBA_1010102;
38         case Media::PixelFormat::BGRA_8888:
39             return PixelFormat::BGRA_8888;
40         case Media::PixelFormat::ALPHA_8:
41             return PixelFormat::ALPHA_8;
42         case Media::PixelFormat::RGBA_F16:
43             return PixelFormat::RGBA_F16;
44         case Media::PixelFormat::UNKNOWN:
45             return PixelFormat::UNKNOWN;
46         case Media::PixelFormat::ARGB_8888:
47             return PixelFormat::ARGB_8888;
48         case Media::PixelFormat::RGB_888:
49             return PixelFormat::RGB_888;
50         case Media::PixelFormat::NV21:
51             return PixelFormat::NV21;
52         case Media::PixelFormat::NV12:
53             return PixelFormat::NV12;
54         case Media::PixelFormat::CMYK:
55             return PixelFormat::CMYK;
56         default:
57             return PixelFormat::UNKNOWN;
58     }
59 }
60 
AlphaTypeConverter(Media::AlphaType alphaType)61 AlphaType PixelMapOhos::AlphaTypeConverter(Media::AlphaType alphaType)
62 {
63     switch (alphaType) {
64         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
65             return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
66         case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
67             return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
68         case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
69             return AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
70         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
71             return AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
72         default:
73             return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
74     }
75 }
76 
Create(std::unique_ptr<Media::PixelMap> && pixmap)77 RefPtr<PixelMap> PixelMap::Create(std::unique_ptr<Media::PixelMap>&& pixmap)
78 {
79     return AceType::MakeRefPtr<PixelMapOhos>(std::move(pixmap));
80 }
81 
CreatePixelMap(void * rawPtr)82 RefPtr<PixelMap> PixelMap::CreatePixelMap(void* rawPtr)
83 {
84     auto* pixmapPtr = reinterpret_cast<std::shared_ptr<Media::PixelMap>*>(rawPtr);
85     if (pixmapPtr == nullptr || *pixmapPtr == nullptr) {
86         LOGW("pixmap pointer is nullptr when CreatePixelMap.");
87         return nullptr;
88     }
89     return AceType::MakeRefPtr<PixelMapOhos>(*pixmapPtr);
90 }
91 
CopyPixelMap(const RefPtr<PixelMap> & pixelMap)92 RefPtr<PixelMap> PixelMap::CopyPixelMap(const RefPtr<PixelMap>& pixelMap)
93 {
94     CHECK_NULL_RETURN(pixelMap, nullptr);
95     OHOS::Media::InitializationOptions opts;
96     auto mediaPixelMap = pixelMap->GetPixelMapSharedPtr();
97     std::unique_ptr<Media::PixelMap> uniquePixelMap = Media::PixelMap::Create(*mediaPixelMap, opts);
98     CHECK_NULL_RETURN(uniquePixelMap, nullptr);
99     Media::PixelMap* pixelMapRelease = uniquePixelMap.release();
100     CHECK_NULL_RETURN(pixelMapRelease, nullptr);
101     std::shared_ptr<Media::PixelMap> newPixelMap(pixelMapRelease);
102     CHECK_NULL_RETURN(newPixelMap, nullptr);
103     return AceType::MakeRefPtr<PixelMapOhos>(newPixelMap);
104 }
105 
DecodeTlv(std::vector<uint8_t> & buff)106 RefPtr<PixelMap> PixelMap::DecodeTlv(std::vector<uint8_t>& buff)
107 {
108     Media::PixelMap* pixelMapRelease = OHOS::Media::PixelMap::DecodeTlv(buff);
109     CHECK_NULL_RETURN(pixelMapRelease, nullptr);
110     std::shared_ptr<Media::PixelMap> newPixelMap(pixelMapRelease);
111     CHECK_NULL_RETURN(newPixelMap, nullptr);
112     return AceType::MakeRefPtr<PixelMapOhos>(newPixelMap);
113 }
114 
EncodeTlv(std::vector<uint8_t> & buff)115 bool PixelMapOhos::EncodeTlv(std::vector<uint8_t>& buff)
116 {
117     CHECK_NULL_RETURN(pixmap_, false);
118     return pixmap_->EncodeTlv(buff);
119 }
120 
GetFromDrawable(void * ptr)121 RefPtr<PixelMap> PixelMap::GetFromDrawable(void* ptr)
122 {
123     CHECK_NULL_RETURN(ptr, nullptr);
124     auto* drawable = reinterpret_cast<Napi::DrawableDescriptor*>(ptr);
125     return AceType::MakeRefPtr<PixelMapOhos>(drawable->GetPixelMap());
126 }
127 
GetPxielMapListFromAnimatedDrawable(void * ptr,std::vector<RefPtr<PixelMap>> & pixelMaps,int32_t & duration,int32_t & iterations)128 bool PixelMap::GetPxielMapListFromAnimatedDrawable(void* ptr, std::vector<RefPtr<PixelMap>>& pixelMaps,
129     int32_t& duration, int32_t& iterations)
130 {
131     CHECK_NULL_RETURN(ptr, false);
132     auto* drawable = reinterpret_cast<Napi::DrawableDescriptor*>(ptr);
133     auto drawableType = drawable->GetDrawableType();
134     if (drawableType != Napi::DrawableDescriptor::DrawableType::ANIMATED) {
135         return false;
136     }
137     auto* animatedDrawable = static_cast<Napi::AnimatedDrawableDescriptor*>(drawable);
138     std::vector<std::shared_ptr<Media::PixelMap>> pixelMapList = animatedDrawable->GetPixelMapList();
139     for (uint32_t i = 0; i < pixelMapList.size(); i++) {
140         pixelMaps.push_back(AceType::MakeRefPtr<PixelMapOhos>(std::move(pixelMapList[i])));
141     }
142     duration = animatedDrawable->GetDuration();
143     iterations = animatedDrawable->GetIterations();
144     return true;
145 }
146 
CreatePixelMapFromDataAbility(void * ptr)147 RefPtr<PixelMap> PixelMap::CreatePixelMapFromDataAbility(void* ptr)
148 {
149     auto* pixmap = reinterpret_cast<Media::PixelMap*>(ptr);
150     CHECK_NULL_RETURN(pixmap, nullptr);
151     return AceType::MakeRefPtr<PixelMapOhos>(std::shared_ptr<Media::PixelMap>(pixmap));
152 }
153 
GetWidth() const154 int32_t PixelMapOhos::GetWidth() const
155 {
156     CHECK_NULL_RETURN(pixmap_, 0);
157     return pixmap_->GetWidth();
158 }
159 
GetHeight() const160 int32_t PixelMapOhos::GetHeight() const
161 {
162     CHECK_NULL_RETURN(pixmap_, 0);
163     return pixmap_->GetHeight();
164 }
165 
GetPixels() const166 const uint8_t* PixelMapOhos::GetPixels() const
167 {
168     CHECK_NULL_RETURN(pixmap_, nullptr);
169     return pixmap_->GetPixels();
170 }
171 
GetPixelFormat() const172 PixelFormat PixelMapOhos::GetPixelFormat() const
173 {
174     CHECK_NULL_RETURN(pixmap_, PixelFormat::UNKNOWN);
175     return PixelFormatConverter(pixmap_->GetPixelFormat());
176 }
177 
GetAlphaType() const178 AlphaType PixelMapOhos::GetAlphaType() const
179 {
180     CHECK_NULL_RETURN(pixmap_, AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN);
181     return AlphaTypeConverter(pixmap_->GetAlphaType());
182 }
183 
GetRowStride() const184 int32_t PixelMapOhos::GetRowStride() const
185 {
186     CHECK_NULL_RETURN(pixmap_, 0);
187     return pixmap_->GetRowStride();
188 }
189 
GetRowBytes() const190 int32_t PixelMapOhos::GetRowBytes() const
191 {
192     CHECK_NULL_RETURN(pixmap_, 0);
193     return pixmap_->GetRowBytes();
194 }
195 
GetByteCount() const196 int32_t PixelMapOhos::GetByteCount() const
197 {
198     CHECK_NULL_RETURN(pixmap_, 0);
199     return pixmap_->GetByteCount();
200 }
201 
GetPixelManager() const202 void* PixelMapOhos::GetPixelManager() const
203 {
204     Media::InitializationOptions opts;
205     CHECK_NULL_RETURN(pixmap_, nullptr);
206     auto newPixelMap = Media::PixelMap::Create(*pixmap_, opts);
207     return reinterpret_cast<void*>(new Media::PixelMapManager(newPixelMap.release()));
208 }
209 
GetRawPixelMapPtr() const210 void* PixelMapOhos::GetRawPixelMapPtr() const
211 {
212     CHECK_NULL_RETURN(pixmap_, nullptr);
213     return pixmap_.get();
214 }
215 
Scale(float xAxis,float yAxis)216 void PixelMapOhos::Scale(float xAxis, float yAxis)
217 {
218     CHECK_NULL_VOID(pixmap_);
219     pixmap_->scale(xAxis, yAxis);
220 }
221 
Scale(float xAxis,float yAxis,const AceAntiAliasingOption & option)222 void PixelMapOhos::Scale(float xAxis, float yAxis, const AceAntiAliasingOption &option)
223 {
224     CHECK_NULL_VOID(pixmap_);
225     switch (option) {
226         case AceAntiAliasingOption::NONE:
227             pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::NONE);
228             break;
229         case AceAntiAliasingOption::LOW:
230             pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
231             break;
232         case AceAntiAliasingOption::MEDIUM:
233             pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::MEDIUM);
234             break;
235         case AceAntiAliasingOption::HIGH:
236             pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::HIGH);
237             break;
238         default:
239             pixmap_->scale(xAxis, yAxis, Media::AntiAliasingOption::NONE);
240             break;
241     }
242 }
243 
GetId()244 std::string PixelMapOhos::GetId()
245 {
246     // using pixmap addr
247     CHECK_NULL_RETURN(pixmap_, "nullptr");
248     std::stringstream strm;
249     strm << pixmap_.get();
250     return strm.str();
251 }
252 
GetModifyId()253 std::string PixelMapOhos::GetModifyId()
254 {
255     return {};
256 }
257 
GetPixelMapSharedPtr()258 std::shared_ptr<Media::PixelMap> PixelMapOhos::GetPixelMapSharedPtr()
259 {
260     return pixmap_;
261 }
262 
GetWritablePixels() const263 void* PixelMapOhos::GetWritablePixels() const
264 {
265     CHECK_NULL_RETURN(pixmap_, nullptr);
266     return pixmap_->GetWritablePixels();
267 }
268 
GetPixelsVec(std::vector<uint8_t> & data) const269 bool PixelMapOhos::GetPixelsVec(std::vector<uint8_t>& data) const
270 {
271     CHECK_NULL_RETURN(pixmap_, false);
272     data.resize(pixmap_->GetByteCount());
273     uint8_t* dst = data.data();
274     uint32_t errCode = pixmap_->ReadPixels(pixmap_->GetByteCount(), dst);
275     if (errCode) {
276         TAG_LOGW(AceLogTag::ACE_IMAGE, "GetPixelsVec error, errCode=%{public}d", errCode);
277         return false;
278     }
279     return true;
280 }
281 
ConvertSkImageToPixmap(const uint32_t * colors,uint32_t colorLength,int32_t width,int32_t height)282 RefPtr<PixelMap> PixelMap::ConvertSkImageToPixmap(
283     const uint32_t* colors, uint32_t colorLength, int32_t width, int32_t height)
284 {
285     Media::InitializationOptions opts;
286     opts.size.width = width;
287     opts.size.height = height;
288     opts.editable = true;
289     std::unique_ptr<Media::PixelMap> pixmap = Media::PixelMap::Create(colors, colorLength, opts);
290     CHECK_NULL_RETURN(pixmap, nullptr);
291     std::shared_ptr<Media::PixelMap> sharedPixelmap(pixmap.release());
292     return AceType::MakeRefPtr<PixelMapOhos>(sharedPixelmap);
293 }
294 
SavePixelMapToFile(const std::string & dst) const295 void PixelMapOhos::SavePixelMapToFile(const std::string& dst) const
296 {
297     int32_t w = pixmap_->GetWidth();
298     int32_t h = pixmap_->GetHeight();
299     int32_t totalSize = pixmap_->GetByteCount();
300     auto rowStride = pixmap_->GetRowStride();
301     uint64_t nowTime = static_cast<uint64_t>(
302         std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
303             .count());
304     std::string filename = std::to_string(nowTime) + "_w" + std::to_string(w) + "_h" + std::to_string(h) +
305                            "_rowStride" + std::to_string(rowStride) + "_byteCount" + std::to_string(totalSize) + dst +
306                            ".dat";
307     auto path = ImageFileCache::GetInstance().ConstructCacheFilePath(filename);
308     std::ofstream outFile(path, std::fstream::out);
309     if (!outFile.is_open()) {
310         TAG_LOGW(AceLogTag::ACE_IMAGE, "write error, path=%{public}s", path.c_str());
311     }
312     outFile.write(reinterpret_cast<const char*>(pixmap_->GetPixels()), totalSize);
313     TAG_LOGI(AceLogTag::ACE_IMAGE, "write success, path=%{public}s", path.c_str());
314 }
315 
GetCropPixelMap(const Rect & srcRect)316 RefPtr<PixelMap> PixelMapOhos::GetCropPixelMap(const Rect& srcRect)
317 {
318     Media::InitializationOptions options;
319     options.size.width = static_cast<int32_t>(srcRect.Width());
320     options.size.height = static_cast<int32_t>(srcRect.Height());
321     options.pixelFormat = Media::PixelFormat::RGBA_8888;
322     options.alphaType = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
323     options.scaleMode = Media::ScaleMode::FIT_TARGET_SIZE;
324 
325     Media::Rect rect {srcRect.Left(), srcRect.Top(), srcRect.Width(), srcRect.Height()};
326     auto resPixelmap = OHOS::Media::PixelMap::Create(*pixmap_, rect, options);
327     return AceType::MakeRefPtr<PixelMapOhos>(std::move(resPixelmap));
328 }
329 
330 } // namespace OHOS::Ace
331