• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "session/host/include/scene_persistence.h"
17 
18 #include <sys/stat.h>
19 
20 #include <hitrace_meter.h>
21 #include <image_packer.h>
22 #include <parameters.h>
23 
24 #include "window_manager_hilog.h"
25 
26 namespace OHOS::Rosen {
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ScenePersistence" };
29 constexpr const char* UNDERLINE_SEPARATOR = "_";
30 constexpr const char* ASTC_IMAGE_FORMAT = "image/astc/4*4";
31 constexpr const char* ASTC_IMAGE_SUFFIX = ".astc";
32 constexpr uint8_t ASTC_IMAGE_QUALITY = 20;
33 
34 constexpr const char* IMAGE_FORMAT = "image/png";
35 constexpr const char* IMAGE_SUFFIX = ".png";
36 constexpr uint8_t IMAGE_QUALITY = 100;
37 constexpr int32_t ICON_IMAGE_WIDTH_HEIGHT_SIZE_LIMIT = 1024;
38 constexpr double ICON_IMAGE_MAX_SCALE = 1;
39 constexpr uint8_t SUCCESS = 0;
40 } // namespace
41 
42 std::string ScenePersistence::snapshotDirectory_;
43 std::string ScenePersistence::updatedIconDirectory_;
44 std::shared_ptr<WSFFRTHelper> ScenePersistence::snapshotFfrtHelper_;
45 bool ScenePersistence::isAstcEnabled_ = false;
46 
CreateSnapshotDir(const std::string & directory)47 bool ScenePersistence::CreateSnapshotDir(const std::string& directory)
48 {
49     snapshotDirectory_ = directory + "/SceneSnapShot/";
50     if (mkdir(snapshotDirectory_.c_str(), S_IRWXU)) {
51         TLOGD(WmsLogTag::WMS_PATTERN, "mkdir failed or the directory already exists");
52         return false;
53     }
54     return true;
55 }
56 
CreateUpdatedIconDir(const std::string & directory)57 bool ScenePersistence::CreateUpdatedIconDir(const std::string& directory)
58 {
59     updatedIconDirectory_ = directory + "/UpdatedIcon/";
60     if (mkdir(updatedIconDirectory_.c_str(), S_IRWXU)) {
61         TLOGD(WmsLogTag::DEFAULT, "mkdir failed or the directory already exists");
62         return false;
63     }
64     return true;
65 }
66 
SetSnapshotCapacity(SnapshotStatus capacity)67 void ScenePersistence::SetSnapshotCapacity(SnapshotStatus capacity)
68 {
69     capacity_ = capacity;
70 }
71 
ScenePersistence(const std::string & bundleName,int32_t persistentId,SnapshotStatus capacity)72 ScenePersistence::ScenePersistence(const std::string& bundleName, int32_t persistentId, SnapshotStatus capacity)
73     : bundleName_(bundleName), persistentId_(persistentId), capacity_(capacity)
74 {
75     InitAstcEnabled();
76     auto suffix = isAstcEnabled_ ? ASTC_IMAGE_SUFFIX : IMAGE_SUFFIX;
77     for (uint32_t screenStatus = SCREEN_UNKNOWN; screenStatus < SCREEN_COUNT; screenStatus++) {
78         for (uint32_t orientation = SNAPSHOT_PORTRAIT; orientation < ORIENTATION_COUNT; orientation++) {
79             snapshotPath_[screenStatus][orientation] = snapshotDirectory_ + bundleName + UNDERLINE_SEPARATOR +
80                 std::to_string(persistentId) + UNDERLINE_SEPARATOR + std::to_string(screenStatus) +
81                 std::to_string(orientation) + suffix;
82         }
83     }
84     snapshotFreeMultiWindowPath_ = snapshotDirectory_ + bundleName + UNDERLINE_SEPARATOR +
85         std::to_string(persistentId) + suffix;
86     updatedIconPath_ = updatedIconDirectory_ + bundleName + IMAGE_SUFFIX;
87     if (snapshotFfrtHelper_ == nullptr) {
88         snapshotFfrtHelper_ = std::make_shared<WSFFRTHelper>();
89     }
90 }
91 
~ScenePersistence()92 ScenePersistence::~ScenePersistence()
93 {
94     TLOGI(WmsLogTag::WMS_PATTERN, "destroyed, persistentId: %{public}d", persistentId_);
95     for (const auto& row : snapshotPath_) {
96         for (auto& snapshotPath : row) {
97             remove(snapshotPath.c_str());
98         }
99     }
100     remove(snapshotFreeMultiWindowPath_.c_str());
101 }
102 
GetSnapshotFfrtHelper() const103 std::shared_ptr<WSFFRTHelper> ScenePersistence::GetSnapshotFfrtHelper() const
104 {
105     return snapshotFfrtHelper_;
106 }
107 
InitAstcEnabled()108 void ScenePersistence::InitAstcEnabled()
109 {
110     static bool isAstcEnabled = system::GetBoolParameter("persist.multimedia.image.astc.enabled", true);
111     isAstcEnabled_ = isAstcEnabled;
112 }
113 
IsAstcEnabled()114 bool ScenePersistence::IsAstcEnabled()
115 {
116     return isAstcEnabled_;
117 }
118 
SaveSnapshot(const std::shared_ptr<Media::PixelMap> & pixelMap,const std::function<void ()> resetSnapshotCallback,SnapshotStatus key,DisplayOrientation rotate,bool freeMultiWindow)119 void ScenePersistence::SaveSnapshot(const std::shared_ptr<Media::PixelMap>& pixelMap,
120     const std::function<void()> resetSnapshotCallback, SnapshotStatus key, DisplayOrientation rotate,
121     bool freeMultiWindow)
122 {
123     savingSnapshotSum_.fetch_add(1);
124     SetIsSavingSnapshot(key, freeMultiWindow, true);
125     TLOGI(WmsLogTag::WMS_PATTERN, "isSavingSnapshot_%{public}d", isSavingSnapshot_[key.first][key.second].load());
126     std::string path = freeMultiWindow ? snapshotFreeMultiWindowPath_ : snapshotPath_[key.first][key.second];
127     auto task = [weakThis = wptr(this), pixelMap, resetSnapshotCallback,
128         savingSnapshotSum = savingSnapshotSum_.load(), key, rotate, path, freeMultiWindow]() {
129         auto scenePersistence = weakThis.promote();
130         if (scenePersistence == nullptr || pixelMap == nullptr ||
131             path.find('/') == std::string::npos) {
132             TLOGNE(WmsLogTag::WMS_PATTERN, "scenePersistence %{public}s nullptr, pixelMap %{public}s nullptr",
133                 scenePersistence == nullptr ? "" : "not", pixelMap == nullptr ? "" : "not");
134             resetSnapshotCallback();
135             return;
136         }
137 
138         TLOGNI(WmsLogTag::WMS_PATTERN, "Save snapshot begin");
139         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SaveSnapshot %s", path.c_str());
140         OHOS::Media::ImagePacker imagePacker;
141         OHOS::Media::PackOption option;
142         option.format = IsAstcEnabled() ? ASTC_IMAGE_FORMAT : IMAGE_FORMAT;
143         option.quality = IsAstcEnabled() ? ASTC_IMAGE_QUALITY : IMAGE_QUALITY;
144         option.numberHint = 1;
145 
146         scenePersistence->SetSnapshotSize(key, freeMultiWindow, { pixelMap->GetWidth(), pixelMap->GetHeight() });
147         std::lock_guard lock(scenePersistence->savingSnapshotMutex_);
148         remove(path.c_str());
149         if (imagePacker.StartPacking(path, option)) {
150             TLOGNE(WmsLogTag::WMS_PATTERN, "Save snapshot failed, starting packing error");
151             resetSnapshotCallback();
152             return;
153         }
154         if (imagePacker.AddImage(*pixelMap)) {
155             TLOGNE(WmsLogTag::WMS_PATTERN, "Save snapshot failed, adding image error");
156             resetSnapshotCallback();
157             return;
158         }
159         int64_t packedSize = 0;
160         if (imagePacker.FinalizePacking(packedSize)) {
161             TLOGNE(WmsLogTag::WMS_PATTERN, "Save snapshot failed, finalizing packing error");
162             resetSnapshotCallback();
163             return;
164         }
165         // If the current num is equals to the latest num, it is the last saveSnapshot task
166         if (savingSnapshotSum == scenePersistence->savingSnapshotSum_.load()) {
167             resetSnapshotCallback();
168         }
169         scenePersistence->rotate_[key.first][key.second] = rotate;
170         TLOGNI(WmsLogTag::WMS_PATTERN, "Save snapshot end, packed size %{public}" PRIu64, packedSize);
171     };
172     snapshotFfrtHelper_->SubmitTask(std::move(task), "SaveSnapshot" + path);
173 }
174 
IsSavingSnapshot(SnapshotStatus key,bool freeMultiWindow)175 bool ScenePersistence::IsSavingSnapshot(SnapshotStatus key, bool freeMultiWindow)
176 {
177     if (freeMultiWindow) {
178         return isSavingSnapshotFreeMultiWindow_.load();
179     }
180     return isSavingSnapshot_[key.first][key.second].load();
181 }
182 
SetIsSavingSnapshot(SnapshotStatus key,bool freeMultiWindow,bool isSavingSnapshot)183 void ScenePersistence::SetIsSavingSnapshot(SnapshotStatus key, bool freeMultiWindow, bool isSavingSnapshot)
184 {
185     if (freeMultiWindow) {
186         isSavingSnapshotFreeMultiWindow_.store(isSavingSnapshot);
187     } else {
188         isSavingSnapshot_[key.first][key.second].store(isSavingSnapshot);
189     }
190 }
191 
ResetSnapshotCache()192 void ScenePersistence::ResetSnapshotCache()
193 {
194     for (auto& row : isSavingSnapshot_) {
195         for (auto& isSavingSnapshot : row) {
196             isSavingSnapshot.store(false);
197         }
198     }
199     isSavingSnapshotFreeMultiWindow_.store(false);
200 }
201 
RenameSnapshotFromOldPersistentId(const int32_t & oldPersistentId)202 void ScenePersistence::RenameSnapshotFromOldPersistentId(const int32_t& oldPersistentId)
203 {
204     auto task = [weakThis = wptr(this), oldPersistentId]() {
205         auto scenePersistence = weakThis.promote();
206         if (scenePersistence == nullptr) {
207             TLOGNE(WmsLogTag::WMS_PATTERN, "scenePersistence is nullptr");
208             return;
209         }
210         for (uint32_t screenStatus = SCREEN_UNKNOWN; screenStatus < SCREEN_COUNT; screenStatus++) {
211             for (uint32_t orientation = SNAPSHOT_PORTRAIT; orientation < ORIENTATION_COUNT; orientation++) {
212                 scenePersistence->RenameSnapshotFromOldPersistentId(oldPersistentId, { screenStatus, orientation });
213             }
214         }
215         auto suffix = scenePersistence->isAstcEnabled_ ? ASTC_IMAGE_SUFFIX : IMAGE_SUFFIX;
216         std::string oldSnapshotFreeMultiWindowPath = snapshotDirectory_ + scenePersistence->bundleName_ +
217             UNDERLINE_SEPARATOR + std::to_string(oldPersistentId) + suffix;
218         auto& snapshotPath = scenePersistence->snapshotFreeMultiWindowPath_;
219         std::lock_guard lock(scenePersistence->savingSnapshotMutex_);
220         int ret = std::rename(oldSnapshotFreeMultiWindowPath.c_str(), snapshotPath.c_str());
221         if (ret == 0) {
222             TLOGNI(WmsLogTag::WMS_PATTERN, "Rename snapshot from %{public}s to %{public}s.",
223                 oldSnapshotFreeMultiWindowPath.c_str(), snapshotPath.c_str());
224         } else {
225             TLOGNW(WmsLogTag::WMS_PATTERN, "Failed to rename snapshot from %{public}s to %{public}s.",
226                 oldSnapshotFreeMultiWindowPath.c_str(), snapshotPath.c_str());
227         }
228     };
229     snapshotFfrtHelper_->SubmitTask(std::move(task), "RenameSnapshotFromOldPersistentId"
230         + std::to_string(oldPersistentId));
231 }
232 
RenameSnapshotFromOldPersistentId(const int32_t & oldPersistentId,SnapshotStatus key)233 void ScenePersistence::RenameSnapshotFromOldPersistentId(const int32_t& oldPersistentId, SnapshotStatus key)
234 {
235     auto& snapshotPath = snapshotPath_[key.first][key.second];
236     auto suffix = isAstcEnabled_ ? ASTC_IMAGE_SUFFIX : IMAGE_SUFFIX;
237     std::string oldSnapshotPath = snapshotDirectory_ + bundleName_ + UNDERLINE_SEPARATOR +
238         std::to_string(oldPersistentId) + UNDERLINE_SEPARATOR + std::to_string(key.first) +
239         std::to_string(key.second) + suffix;
240     std::lock_guard lock(savingSnapshotMutex_);
241     int ret = std::rename(oldSnapshotPath.c_str(), snapshotPath.c_str());
242     if (ret == 0) {
243         TLOGI(WmsLogTag::WMS_PATTERN, "Rename snapshot from %{public}s to %{public}s.",
244             oldSnapshotPath.c_str(), snapshotPath.c_str());
245     } else {
246         TLOGW(WmsLogTag::WMS_PATTERN, "Failed to rename snapshot from %{public}s to %{public}s.",
247             oldSnapshotPath.c_str(), snapshotPath.c_str());
248     }
249 }
250 
GetSnapshotFilePath(SnapshotStatus & key,bool useKey,bool freeMultiWindow)251 std::string ScenePersistence::GetSnapshotFilePath(SnapshotStatus& key, bool useKey, bool freeMultiWindow)
252 {
253     if (freeMultiWindow) {
254         return snapshotFreeMultiWindowPath_;
255     }
256     if (useKey || HasSnapshot(key, false)) {
257         return snapshotPath_[key.first][key.second];
258     }
259     if (FindClosestFormSnapshot(key)) {
260         return snapshotPath_[key.first][key.second];
261     }
262     TLOGW(WmsLogTag::WMS_PATTERN, "Failed");
263     return snapshotPath_[SCREEN_UNKNOWN][SNAPSHOT_PORTRAIT];
264 }
265 
FindClosestFormSnapshot(SnapshotStatus & key)266 bool ScenePersistence::FindClosestFormSnapshot(SnapshotStatus& key)
267 {
268     std::lock_guard lock(hasSnapshotMutex_);
269     for (uint32_t orientation = SNAPSHOT_PORTRAIT; orientation < capacity_.second; orientation++) {
270         if (hasSnapshot_[key.first][orientation]) {
271             key.second = orientation;
272             return true;
273         }
274     }
275     bool isFolded = (key.first == SCREEN_FOLDED);
276     if (isFolded) {
277         for (uint32_t screenStatus = SCREEN_EXPAND; screenStatus < capacity_.first; screenStatus--) {
278             if (hasSnapshot_[screenStatus][key.second]) {
279                 key.first = screenStatus;
280                 return true;
281             }
282         }
283         uint32_t orientation = (key.second == SNAPSHOT_PORTRAIT) ? SNAPSHOT_LANDSCAPE : SNAPSHOT_PORTRAIT;
284         for (uint32_t screenStatus = SCREEN_EXPAND; screenStatus < capacity_.first; screenStatus--) {
285             if (hasSnapshot_[screenStatus][orientation]) {
286                 key = { screenStatus, orientation };
287                 return true;
288             }
289         }
290         return false;
291     }
292     for (uint32_t screenStatus = SCREEN_UNKNOWN; screenStatus < capacity_.first; screenStatus++) {
293         if (hasSnapshot_[screenStatus][key.second]) {
294             key.first = screenStatus;
295             return true;
296         }
297     }
298     uint32_t orientation = (key.second == SNAPSHOT_PORTRAIT) ? SNAPSHOT_LANDSCAPE : SNAPSHOT_PORTRAIT;
299     for (uint32_t screenStatus = SCREEN_UNKNOWN; screenStatus < capacity_.first; screenStatus++) {
300         if (hasSnapshot_[screenStatus][orientation]) {
301             key = { screenStatus, orientation };
302             return true;
303         }
304     }
305     return false;
306 }
307 
SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap> & pixelMap)308 void ScenePersistence::SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap>& pixelMap)
309 {
310     if (pixelMap == nullptr || updatedIconPath_.find('/') == std::string::npos) {
311         return;
312     }
313 
314     OHOS::Media::ImagePacker imagePacker;
315     OHOS::Media::PackOption option;
316     option.format = IMAGE_FORMAT;
317     option.quality = IMAGE_QUALITY;
318     option.numberHint = 1;
319     if (pixelMap->GetWidth() > ICON_IMAGE_WIDTH_HEIGHT_SIZE_LIMIT ||
320         pixelMap->GetHeight() > ICON_IMAGE_WIDTH_HEIGHT_SIZE_LIMIT) {
321         // large image need scale
322         double xScale = pixelMap->GetWidth() > ICON_IMAGE_WIDTH_HEIGHT_SIZE_LIMIT ?
323             ICON_IMAGE_WIDTH_HEIGHT_SIZE_LIMIT / static_cast<double>(pixelMap->GetWidth()) : ICON_IMAGE_MAX_SCALE;
324         double yScale = pixelMap->GetHeight() > ICON_IMAGE_WIDTH_HEIGHT_SIZE_LIMIT ?
325             ICON_IMAGE_WIDTH_HEIGHT_SIZE_LIMIT / static_cast<double>(pixelMap->GetHeight()) : ICON_IMAGE_MAX_SCALE;
326         pixelMap->scale(xScale, yScale, Media::AntiAliasingOption::MEDIUM);
327     }
328     if (remove(updatedIconPath_.c_str())) {
329         TLOGD(WmsLogTag::DEFAULT, "Failed to delete old file");
330     }
331     if (imagePacker.StartPacking(GetUpdatedIconPath(), option)) {
332         TLOGE(WmsLogTag::DEFAULT, "Save updated icon failed, starting packing error");
333         return;
334     }
335     if (imagePacker.AddImage(*pixelMap)) {
336         TLOGE(WmsLogTag::DEFAULT, "Save updated icon failed, adding image error");
337         return;
338     }
339     int64_t packedSize = 0;
340     if (imagePacker.FinalizePacking(packedSize)) {
341         TLOGE(WmsLogTag::DEFAULT, "Save updated icon failed, finalizing packing error");
342         return;
343     }
344     TLOGD(WmsLogTag::DEFAULT, "SaveUpdatedIcon finished");
345 }
346 
GetUpdatedIconPath() const347 std::string ScenePersistence::GetUpdatedIconPath() const
348 {
349     return updatedIconPath_;
350 }
351 
SetSnapshotSize(SnapshotStatus key,bool freeMultiWindow,std::pair<uint32_t,uint32_t> size)352 void ScenePersistence::SetSnapshotSize(SnapshotStatus key, bool freeMultiWindow, std::pair<uint32_t, uint32_t> size)
353 {
354     std::lock_guard lock(snapshotSizeMutex_);
355     if (freeMultiWindow) {
356         snapshotFreeMultiWindowSize_ = size;
357     } else {
358         snapshotSize_[key.first][key.second] = size;
359     }
360 }
361 
GetSnapshotSize(SnapshotStatus key,bool freeMultiWindow) const362 std::pair<uint32_t, uint32_t> ScenePersistence::GetSnapshotSize(SnapshotStatus key, bool freeMultiWindow) const
363 {
364     std::lock_guard lock(snapshotSizeMutex_);
365     if (freeMultiWindow) {
366         return snapshotFreeMultiWindowSize_;
367     }
368     return snapshotSize_[key.first][key.second];
369 }
370 
SetHasSnapshot(bool hasSnapshot,SnapshotStatus key)371 void ScenePersistence::SetHasSnapshot(bool hasSnapshot, SnapshotStatus key)
372 {
373     std::lock_guard lock(hasSnapshotMutex_);
374     hasSnapshot_[key.first][key.second] = hasSnapshot;
375 }
376 
SetHasSnapshotFreeMultiWindow(bool hasSnapshot)377 void ScenePersistence::SetHasSnapshotFreeMultiWindow(bool hasSnapshot)
378 {
379     std::lock_guard lock(hasSnapshotMutex_);
380     hasSnapshotFreeMultiWindow_ = hasSnapshot;
381 }
382 
HasSnapshot() const383 bool ScenePersistence::HasSnapshot() const
384 {
385     std::lock_guard lock(hasSnapshotMutex_);
386     for (const auto& row : hasSnapshot_) {
387         for (const auto& hasSnapshot : row) {
388             if (hasSnapshot) {
389                 return true;
390             }
391         }
392     }
393     return hasSnapshotFreeMultiWindow_;
394 }
395 
HasSnapshot(SnapshotStatus key,bool freeMultiWindow) const396 bool ScenePersistence::HasSnapshot(SnapshotStatus key, bool freeMultiWindow) const
397 {
398     std::lock_guard lock(hasSnapshotMutex_);
399     if (freeMultiWindow) {
400         return hasSnapshotFreeMultiWindow_;
401     }
402     return hasSnapshot_[key.first][key.second];
403 }
404 
ClearSnapshot(SnapshotStatus key)405 void ScenePersistence::ClearSnapshot(SnapshotStatus key)
406 {
407     std::lock_guard lock(hasSnapshotMutex_);
408     for (auto& row : hasSnapshot_) {
409         for (auto& hasSnapshot : row) {
410             hasSnapshot = false;
411         }
412     }
413     hasSnapshotFreeMultiWindow_ = false;
414     hasSnapshot_[key.first][key.second] = true;
415 }
416 
IsSnapshotExisted(SnapshotStatus key)417 bool ScenePersistence::IsSnapshotExisted(SnapshotStatus key)
418 {
419     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "IsSnapshotExisted");
420     struct stat buf;
421     if (stat(snapshotPath_[key.first][key.second].c_str(), &buf)) {
422         TLOGD(WmsLogTag::WMS_PATTERN, "Snapshot file %{public}s does not exist",
423             snapshotPath_[key.first][key.second].c_str());
424         return false;
425     }
426     if (!S_ISREG(buf.st_mode)) {
427         return false;
428     }
429     SetHasSnapshot(true, key);
430     return true;
431 }
432 
GetLocalSnapshotPixelMap(const float oriScale,const float newScale,SnapshotStatus key,bool freeMultiWindow)433 std::shared_ptr<Media::PixelMap> ScenePersistence::GetLocalSnapshotPixelMap(const float oriScale,
434     const float newScale, SnapshotStatus key, bool freeMultiWindow)
435 {
436     if (!IsSnapshotExisted(key)) {
437         TLOGE(WmsLogTag::WMS_PATTERN, "local snapshot pic is not existed");
438         return nullptr;
439     }
440 
441     uint32_t errorCode = 0;
442     Media::SourceOptions sourceOpts;
443     sourceOpts.formatHint = IsAstcEnabled() ? ASTC_IMAGE_FORMAT : IMAGE_FORMAT;
444     std::string path = GetSnapshotFilePath(key, true, freeMultiWindow);
445     std::lock_guard lock(savingSnapshotMutex_);
446     auto imageSource = Media::ImageSource::CreateImageSource(path, sourceOpts, errorCode);
447     if (!imageSource) {
448         TLOGE(WmsLogTag::WMS_PATTERN, "create image source fail, errCode: %{public}u", errorCode);
449         return nullptr;
450     }
451 
452     Media::ImageInfo info;
453     int32_t decoderWidth = 0;
454     int32_t decoderHeight = 0;
455     errorCode = imageSource->GetImageInfo(info);
456     if (errorCode == Rosen::SUCCESS) {
457         decoderWidth = info.size.width;
458         decoderHeight = info.size.height;
459     }
460     Media::DecodeOptions decodeOpts;
461     decodeOpts.desiredPixelFormat = Media::PixelFormat::RGBA_8888;
462     if (oriScale != 0 && decoderWidth > 0 && decoderHeight > 0) {
463         auto isNeedToScale = newScale < oriScale;
464         decodeOpts.desiredSize.width = isNeedToScale ?
465             static_cast<int>(decoderWidth * newScale / oriScale) : decoderWidth;
466         decodeOpts.desiredSize.height = isNeedToScale ?
467             static_cast<int>(decoderHeight * newScale / oriScale) : decoderHeight;
468     }
469     return imageSource->CreatePixelMap(decodeOpts, errorCode);
470 }
471 } // namespace OHOS::Rosen
472