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