1 /*
2 * Copyright (c) 2021 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 "mission_data_storage.h"
17
18 #include "directory_ex.h"
19 #include "file_ex.h"
20 #include "hilog_wrapper.h"
21 #include "image_source.h"
22 #include "media_errors.h"
23 #include "mission_info_mgr.h"
24 #ifdef SUPPORT_GRAPHICS
25 #include <cstdio>
26 #include <setjmp.h>
27 #include "jpeglib.h"
28 #include "securec.h"
29 #endif
30
31 namespace OHOS {
32 namespace AAFwk {
33 #ifdef SUPPORT_GRAPHICS
34 constexpr int32_t RGB565_PIXEL_BYTES = 2;
35 constexpr int32_t RGB888_PIXEL_BYTES = 3;
36 constexpr int32_t RGBA8888_PIXEL_BYTES = 4;
37
38 constexpr uint8_t B_INDEX = 0;
39 constexpr uint8_t G_INDEX = 1;
40 constexpr uint8_t R_INDEX = 2;
41 constexpr uint8_t SHIFT_2_BIT = 2;
42 constexpr uint8_t SHITF_3_BIT = 3;
43 constexpr uint8_t SHIFT_5_BIT = 5;
44 constexpr uint8_t SHIFT_8_BIT = 8;
45 constexpr uint8_t SHIFT_11_BIT = 11;
46 constexpr uint8_t SHIFT_16_BIT = 16;
47
48 constexpr uint16_t RGB565_MASK_BLUE = 0xF800;
49 constexpr uint16_t RGB565_MASK_GREEN = 0x07E0;
50 constexpr uint16_t RGB565_MASK_RED = 0x001F;
51 constexpr uint32_t RGBA8888_MASK_BLUE = 0x000000FF;
52 constexpr uint32_t RGBA8888_MASK_GREEN = 0x0000FF00;
53 constexpr uint32_t RGBA8888_MASK_RED = 0x00FF0000;
54
55 const mode_t MODE = 0770;
56
57 struct mission_error_mgr : public jpeg_error_mgr {
58 jmp_buf environment;
59 };
60
mission_error_exit(j_common_ptr cinfo)61 METHODDEF(void) mission_error_exit(j_common_ptr cinfo)
62 {
63 if (cinfo == nullptr || cinfo->err == nullptr) {
64 HILOG_ERROR("%{public}s param is invalid.", __func__);
65 return;
66 }
67 auto err = (mission_error_mgr*)cinfo->err;
68 longjmp(err->environment, 1);
69 }
70 #endif
71
MissionDataStorage(int userId)72 MissionDataStorage::MissionDataStorage(int userId)
73 {
74 userId_ = userId;
75 }
76
~MissionDataStorage()77 MissionDataStorage::~MissionDataStorage()
78 {}
79
SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler> & handler)80 void MissionDataStorage::SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler> &handler)
81 {
82 handler_ = handler;
83 }
84
LoadAllMissionInfo(std::list<InnerMissionInfo> & missionInfoList)85 bool MissionDataStorage::LoadAllMissionInfo(std::list<InnerMissionInfo> &missionInfoList)
86 {
87 std::vector<std::string> fileNameVec;
88 std::vector<int32_t> tempMissions;
89 std::string dirPath = GetMissionDataDirPath();
90 OHOS::GetDirFiles(dirPath, fileNameVec);
91
92 for (auto fileName : fileNameVec) {
93 if (!CheckFileNameValid(fileName)) {
94 HILOG_ERROR("load mission info: file name %{public}s invalid.", fileName.c_str());
95 continue;
96 }
97
98 std::string content;
99 bool loadFile = OHOS::LoadStringFromFile(fileName, content);
100 if (!loadFile) {
101 HILOG_ERROR("load string from file %{public}s failed.", fileName.c_str());
102 continue;
103 }
104
105 InnerMissionInfo misssionInfo;
106 if (!misssionInfo.FromJsonStr(content)) {
107 HILOG_ERROR("parse mission info failed. file: %{public}s", fileName.c_str());
108 continue;
109 }
110 if (misssionInfo.isTemporary) {
111 tempMissions.push_back(misssionInfo.missionInfo.id);
112 continue;
113 }
114 missionInfoList.push_back(misssionInfo);
115 }
116
117 for (auto missionId : tempMissions) {
118 DeleteMissionInfo(missionId);
119 }
120 return true;
121 }
122
SaveMissionInfo(const InnerMissionInfo & missionInfo)123 void MissionDataStorage::SaveMissionInfo(const InnerMissionInfo &missionInfo)
124 {
125 std::string filePath = GetMissionDataFilePath(missionInfo.missionInfo.id);
126 std::string dirPath = OHOS::ExtractFilePath(filePath);
127 if (!OHOS::FileExists(dirPath)) {
128 bool createDir = OHOS::ForceCreateDirectory(dirPath);
129 if (!createDir) {
130 HILOG_ERROR("create dir %{public}s failed.", dirPath.c_str());
131 return;
132 }
133 chmod(dirPath.c_str(), MODE);
134 }
135
136 std::string jsonStr = missionInfo.ToJsonStr();
137 bool saveMissionFile = OHOS::SaveStringToFile(filePath, jsonStr, true);
138 if (!saveMissionFile) {
139 HILOG_ERROR("save mission file %{public}s failed.", filePath.c_str());
140 }
141 }
142
DeleteMissionInfo(int missionId)143 void MissionDataStorage::DeleteMissionInfo(int missionId)
144 {
145 std::string filePath = GetMissionDataFilePath(missionId);
146 bool removeMissionFile = OHOS::RemoveFile(filePath);
147 if (!removeMissionFile) {
148 HILOG_ERROR("remove mission file %{public}s failed.", filePath.c_str());
149 return;
150 }
151 DeleteMissionSnapshot(missionId);
152 }
153
SaveMissionSnapshot(int32_t missionId,const MissionSnapshot & missionSnapshot)154 void MissionDataStorage::SaveMissionSnapshot(int32_t missionId, const MissionSnapshot& missionSnapshot)
155 {
156 #ifdef SUPPORT_GRAPHICS
157 HILOG_INFO("snapshot: save snapshot from cache, missionId = %{public}d", missionId);
158 SaveCachedSnapshot(missionId, missionSnapshot);
159 SaveSnapshotFile(missionId, missionSnapshot);
160 HILOG_INFO("snapshot: delete snapshot from cache, missionId = %{public}d", missionId);
161 DeleteCachedSnapshot(missionId);
162 #endif
163 }
164
DeleteMissionSnapshot(int32_t missionId)165 void MissionDataStorage::DeleteMissionSnapshot(int32_t missionId)
166 {
167 #ifdef SUPPORT_GRAPHICS
168 DeleteMissionSnapshot(missionId, false);
169 DeleteMissionSnapshot(missionId, true);
170 #endif
171 }
172
GetMissionSnapshot(int32_t missionId,MissionSnapshot & missionSnapshot,bool isLowResolution)173 bool MissionDataStorage::GetMissionSnapshot(int32_t missionId, MissionSnapshot& missionSnapshot, bool isLowResolution)
174 {
175 #ifdef SUPPORT_GRAPHICS
176 if (GetCachedSnapshot(missionId, missionSnapshot)) {
177 if (isLowResolution) {
178 missionSnapshot.snapshot = GetReducedPixelMap(missionSnapshot.snapshot);
179 }
180 HILOG_INFO("snapshot: GetMissionSnapshot from cache, missionId = %{public}d", missionId);
181 return true;
182 }
183
184 auto pixelMap = GetPixelMap(missionId, isLowResolution);
185 if (!pixelMap) {
186 HILOG_ERROR("%{public}s: GetPixelMap failed.", __func__);
187 return false;
188 }
189 missionSnapshot.snapshot = std::move(pixelMap);
190 #endif
191 return true;
192 }
193
GetMissionDataDirPath() const194 std::string MissionDataStorage::GetMissionDataDirPath() const
195 {
196 return std::string(TASK_DATA_FILE_BASE_PATH) + "/" + std::to_string(userId_) + "/"
197 + std::string(MISSION_DATA_FILE_PATH);
198 }
199
GetMissionDataFilePath(int missionId)200 std::string MissionDataStorage::GetMissionDataFilePath(int missionId)
201 {
202 return GetMissionDataDirPath() + "/"
203 + MISSION_JSON_FILE_PREFIX + "_" + std::to_string(missionId) + JSON_FILE_SUFFIX;
204 }
205
GetMissionSnapshotPath(int32_t missionId,bool isLowResolution) const206 std::string MissionDataStorage::GetMissionSnapshotPath(int32_t missionId, bool isLowResolution) const
207 {
208 std::string filePath = GetMissionDataDirPath() + FILE_SEPARATOR + MISSION_JSON_FILE_PREFIX +
209 UNDERLINE_SEPARATOR + std::to_string(missionId);
210 if (isLowResolution) {
211 filePath = filePath + UNDERLINE_SEPARATOR + LOW_RESOLUTION_FLAG;
212 }
213 filePath = filePath + JPEG_FILE_SUFFIX;
214 return filePath;
215 }
216
CheckFileNameValid(const std::string & fileName)217 bool MissionDataStorage::CheckFileNameValid(const std::string &fileName)
218 {
219 std::string fileNameExcludePath = OHOS::ExtractFileName(fileName);
220 if (fileNameExcludePath.find(MISSION_JSON_FILE_PREFIX) != 0) {
221 return false;
222 }
223
224 if (fileNameExcludePath.find("_") != std::string(MISSION_JSON_FILE_PREFIX).length()) {
225 return false;
226 }
227
228 if (fileNameExcludePath.find(JSON_FILE_SUFFIX) != fileNameExcludePath.length()
229 - std::string(JSON_FILE_SUFFIX).length()) {
230 return false;
231 }
232
233 size_t missionIdLength = fileNameExcludePath.find(JSON_FILE_SUFFIX) - fileNameExcludePath.find("_") - 1;
234 std::string missionId = fileNameExcludePath.substr(fileNameExcludePath.find("_") + 1, missionIdLength);
235 for (auto ch : missionId) {
236 if (!isdigit(ch)) {
237 return false;
238 }
239 }
240
241 return true;
242 }
243
244 #ifdef SUPPORT_GRAPHICS
SaveSnapshotFile(int32_t missionId,const MissionSnapshot & missionSnapshot)245 void MissionDataStorage::SaveSnapshotFile(int32_t missionId, const MissionSnapshot& missionSnapshot)
246 {
247 SaveSnapshotFile(missionId, missionSnapshot.snapshot, missionSnapshot.isPrivate, false);
248 SaveSnapshotFile(missionId, GetReducedPixelMap(missionSnapshot.snapshot), missionSnapshot.isPrivate, true);
249 DelayedSingleton<MissionInfoMgr>::GetInstance()->CompleteSaveSnapshot(missionId);
250 }
251
SaveSnapshotFile(int32_t missionId,const std::shared_ptr<OHOS::Media::PixelMap> & snapshot,bool isPrivate,bool isLowResolution)252 void MissionDataStorage::SaveSnapshotFile(int32_t missionId, const std::shared_ptr<OHOS::Media::PixelMap>& snapshot,
253 bool isPrivate, bool isLowResolution)
254 {
255 if (!snapshot) {
256 return;
257 }
258
259 std::string filePath = GetMissionSnapshotPath(missionId, isLowResolution);
260 std::string dirPath = OHOS::ExtractFilePath(filePath);
261 if (!OHOS::FileExists(dirPath)) {
262 bool createDir = OHOS::ForceCreateDirectory(dirPath);
263 if (!createDir) {
264 HILOG_ERROR("snapshot: create dir %{public}s failed.", dirPath.c_str());
265 return;
266 }
267 chmod(dirPath.c_str(), MODE);
268 }
269
270 if (isPrivate) {
271 HILOG_DEBUG("snapshot: the param isPrivate is true.");
272 ssize_t dataLength = snapshot->GetWidth() * snapshot->GetHeight() * RGB888_PIXEL_BYTES;
273 uint8_t* data = (uint8_t*) malloc(dataLength);
274 if (data == nullptr) {
275 HILOG_ERROR("malloc failed.");
276 return;
277 }
278 if (memset_s(data, dataLength, 0xff, dataLength) == EOK) {
279 WriteRgb888ToJpeg(filePath.c_str(), snapshot->GetWidth(), snapshot->GetHeight(), data);
280 }
281 free(data);
282 } else {
283 if (snapshot->GetPixelFormat() == Media::PixelFormat::RGB_565) {
284 SaveRGB565Image(snapshot, filePath.c_str());
285 } else if (snapshot->GetPixelFormat() == Media::PixelFormat::RGBA_8888) {
286 SaveRGBA8888Image(snapshot, filePath.c_str());
287 } else if (snapshot->GetPixelFormat() == Media::PixelFormat::RGB_888) {
288 WriteRgb888ToJpeg(filePath.c_str(), snapshot->GetWidth(), snapshot->GetHeight(), snapshot->GetPixels());
289 } else {
290 HILOG_ERROR("snapshot: invalid pixel format.");
291 }
292 }
293 }
294
GetReducedPixelMap(const std::shared_ptr<OHOS::Media::PixelMap> & snapshot)295 std::shared_ptr<OHOS::Media::PixelMap> MissionDataStorage::GetReducedPixelMap(
296 const std::shared_ptr<OHOS::Media::PixelMap>& snapshot)
297 {
298 if (!snapshot) {
299 return nullptr;
300 }
301
302 OHOS::Media::InitializationOptions options;
303 options.size.width = snapshot->GetWidth() / SCALE;
304 options.size.height = snapshot->GetHeight() / SCALE;
305 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*snapshot, options);
306 return std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
307 }
308
GetCachedSnapshot(int32_t missionId,MissionSnapshot & missionSnapshot)309 bool MissionDataStorage::GetCachedSnapshot(int32_t missionId, MissionSnapshot& missionSnapshot)
310 {
311 std::lock_guard<std::mutex> lock(cachedPixelMapMutex_);
312 auto pixelMap = cachedPixelMap_.find(missionId);
313 if (pixelMap != cachedPixelMap_.end()) {
314 missionSnapshot.snapshot = pixelMap->second;
315 return true;
316 }
317 return false;
318 }
319
SaveCachedSnapshot(int32_t missionId,const MissionSnapshot & missionSnapshot)320 bool MissionDataStorage::SaveCachedSnapshot(int32_t missionId, const MissionSnapshot& missionSnapshot)
321 {
322 std::lock_guard<std::mutex> lock(cachedPixelMapMutex_);
323 auto result = cachedPixelMap_.insert_or_assign(missionId, missionSnapshot.snapshot);
324 if (!result.second) {
325 HILOG_ERROR("snapshot: save snapshot cache failed, missionId = %{public}d", missionId);
326 return false;
327 }
328 return true;
329 }
330
DeleteCachedSnapshot(int32_t missionId)331 bool MissionDataStorage::DeleteCachedSnapshot(int32_t missionId)
332 {
333 std::lock_guard<std::mutex> lock(cachedPixelMapMutex_);
334 auto result = cachedPixelMap_.erase(missionId);
335 if (result != 1) {
336 HILOG_ERROR("snapshot: delete snapshot cache failed, missionId = %{public}d", missionId);
337 return false;
338 }
339 return true;
340 }
341
DeleteMissionSnapshot(int32_t missionId,bool isLowResolution)342 void MissionDataStorage::DeleteMissionSnapshot(int32_t missionId, bool isLowResolution)
343 {
344 std::string filePath = GetMissionSnapshotPath(missionId, isLowResolution);
345 std::string dirPath = OHOS::ExtractFilePath(filePath);
346 if (!OHOS::FileExists(filePath)) {
347 HILOG_WARN("snapshot: remove snapshot file %{public}s failed, file not exists", filePath.c_str());
348 return;
349 }
350 bool removeResult = OHOS::RemoveFile(filePath);
351 if (!removeResult) {
352 HILOG_ERROR("snapshot: remove snapshot file %{public}s failed.", filePath.c_str());
353 }
354 }
355
GetSnapshot(int missionId,bool isLowResolution) const356 std::shared_ptr<Media::PixelMap> MissionDataStorage::GetSnapshot(int missionId, bool isLowResolution) const
357 {
358 auto pixelMapPtr = GetPixelMap(missionId, isLowResolution);
359 if (!pixelMapPtr) {
360 HILOG_ERROR("%{public}s: GetPixelMap failed.", __func__);
361 return nullptr;
362 }
363 return std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
364 }
365
GetPixelMap(int missionId,bool isLowResolution) const366 std::unique_ptr<Media::PixelMap> MissionDataStorage::GetPixelMap(int missionId, bool isLowResolution) const
367 {
368 std::string filePath = GetMissionSnapshotPath(missionId, isLowResolution);
369 if (!OHOS::FileExists(filePath)) {
370 HILOG_INFO("snapshot: storage snapshot not exists, missionId = %{public}d", missionId);
371 return nullptr;
372 }
373 uint32_t errCode = 0;
374 Media::SourceOptions sourceOptions;
375 auto imageSource = Media::ImageSource::CreateImageSource(filePath, sourceOptions, errCode);
376 if (errCode != OHOS::Media::SUCCESS) {
377 HILOG_ERROR("snapshot: CreateImageSource failed, errCode = %{public}d", errCode);
378 return nullptr;
379 }
380 Media::DecodeOptions decodeOptions;
381 decodeOptions.allocatorType = Media::AllocatorType::SHARE_MEM_ALLOC;
382 auto pixelMapPtr = imageSource->CreatePixelMap(decodeOptions, errCode);
383 if (errCode != OHOS::Media::SUCCESS) {
384 HILOG_ERROR("snapshot: CreatePixelMap failed, errCode = %{public}d", errCode);
385 return nullptr;
386 }
387 return pixelMapPtr;
388 }
389
WriteRgb888ToJpeg(const char * fileName,uint32_t width,uint32_t height,const uint8_t * data)390 void MissionDataStorage::WriteRgb888ToJpeg(const char* fileName, uint32_t width, uint32_t height, const uint8_t* data)
391 {
392 if (data == nullptr) {
393 HILOG_ERROR("snapshot: data error, nullptr!\n");
394 return;
395 }
396
397 FILE *file = fopen(fileName, "wb");
398 if (file == nullptr) {
399 HILOG_ERROR("snapshot: open file [%s] error, nullptr!\n", fileName);
400 return;
401 }
402
403 struct jpeg_compress_struct jpeg;
404 struct mission_error_mgr jerr;
405 jpeg.err = jpeg_std_error(&jerr);
406 jerr.error_exit = mission_error_exit;
407 if (setjmp(jerr.environment)) {
408 jpeg_destroy_compress(&jpeg);
409 (void)fclose(file);
410 file = nullptr;
411 HILOG_ERROR("snapshot: lib jpeg exit with error!");
412 return;
413 }
414
415 jpeg_create_compress(&jpeg);
416 jpeg.image_width = width;
417 jpeg.image_height = height;
418 jpeg.input_components = RGB888_PIXEL_BYTES;
419 jpeg.in_color_space = JCS_RGB;
420 jpeg_set_defaults(&jpeg);
421
422 constexpr int32_t quality = 75;
423 jpeg_set_quality(&jpeg, quality, TRUE);
424
425 jpeg_stdio_dest(&jpeg, file);
426 jpeg_start_compress(&jpeg, TRUE);
427 JSAMPROW rowPointer[1];
428 for (uint32_t i = 0; i < jpeg.image_height; i++) {
429 rowPointer[0] = const_cast<uint8_t *>(data + i * jpeg.image_width * RGB888_PIXEL_BYTES);
430 (void)jpeg_write_scanlines(&jpeg, rowPointer, 1);
431 }
432
433 jpeg_finish_compress(&jpeg);
434 (void)fclose(file);
435 file = nullptr;
436 jpeg_destroy_compress(&jpeg);
437 }
438
439 // only valid for little-endian order.
RGB565ToRGB888(const uint16_t * rgb565Buf,int32_t rgb565Size,uint8_t * rgb888Buf,int32_t rgb888Size)440 bool MissionDataStorage::RGB565ToRGB888(const uint16_t *rgb565Buf, int32_t rgb565Size,
441 uint8_t *rgb888Buf, int32_t rgb888Size)
442 {
443 if (rgb565Buf == nullptr || rgb565Size <= 0 || rgb888Buf == nullptr || rgb888Size <= 0) {
444 HILOG_ERROR("%{public}s: params are invalid.", __func__);
445 return false;
446 }
447
448 if (rgb888Size < rgb565Size * RGB888_PIXEL_BYTES) {
449 HILOG_ERROR("%{public}s: rgb888Size are invalid.", __func__);
450 return false;
451 }
452
453 for (int32_t i = 0; i < rgb565Size; i++) {
454 rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] = (rgb565Buf[i] & RGB565_MASK_RED);
455 rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] = (rgb565Buf[i] & RGB565_MASK_GREEN) >> SHIFT_5_BIT;
456 rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] = (rgb565Buf[i] & RGB565_MASK_BLUE) >> SHIFT_11_BIT;
457 rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] <<= SHITF_3_BIT;
458 rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] <<= SHIFT_2_BIT;
459 rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] <<= SHITF_3_BIT;
460 }
461
462 return true;
463 }
464
RGBA8888ToRGB888(const uint32_t * rgba8888Buf,int32_t rgba8888Size,uint8_t * rgb888Buf,int32_t rgb888Size)465 bool MissionDataStorage::RGBA8888ToRGB888(const uint32_t *rgba8888Buf, int32_t rgba8888Size,
466 uint8_t *rgb888Buf, int32_t rgb888Size)
467 {
468 if (rgba8888Buf == nullptr || rgba8888Size <= 0 || rgb888Buf == nullptr || rgb888Size <= 0) {
469 HILOG_ERROR("%{public}s: params are invalid.", __func__);
470 return false;
471 }
472
473 if (rgb888Size < rgba8888Size * RGB888_PIXEL_BYTES) {
474 HILOG_ERROR("%{public}s: rgb888Size are invalid.", __func__);
475 return false;
476 }
477
478 for (int32_t i = 0; i < rgba8888Size; i++) {
479 rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] = (rgba8888Buf[i] & RGBA8888_MASK_RED) >> SHIFT_16_BIT;
480 rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] = (rgba8888Buf[i] & RGBA8888_MASK_GREEN) >> SHIFT_8_BIT;
481 rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] = rgba8888Buf[i] & RGBA8888_MASK_BLUE;
482 }
483
484 return true;
485 }
486
SaveRGB565Image(const std::shared_ptr<Media::PixelMap> & frame,const char * fileName)487 void MissionDataStorage::SaveRGB565Image(const std::shared_ptr<Media::PixelMap> &frame, const char* fileName)
488 {
489 HILOG_DEBUG("%{public}s was called.", __func__);
490 int32_t rgb888Size = (frame->GetByteCount() / RGB565_PIXEL_BYTES) * RGB888_PIXEL_BYTES;
491 uint8_t *rgb888 = new uint8_t[rgb888Size];
492 const uint16_t *rgb565Data = reinterpret_cast<const uint16_t *>(frame->GetPixels());
493 auto ret = RGB565ToRGB888(rgb565Data, frame->GetByteCount() / RGB565_PIXEL_BYTES, rgb888, rgb888Size);
494 if (ret) {
495 HILOG_DEBUG("snapshot: convert rgb565 to rgb888 successfully.");
496 WriteRgb888ToJpeg(fileName, frame->GetWidth(), frame->GetHeight(), rgb888);
497 }
498 delete [] rgb888;
499 }
500
SaveRGBA8888Image(const std::shared_ptr<Media::PixelMap> & frame,const char * fileName)501 void MissionDataStorage::SaveRGBA8888Image(const std::shared_ptr<Media::PixelMap> &frame, const char* fileName)
502 {
503 HILOG_DEBUG("%{public}s was called.", __func__);
504 int32_t rgb888Size = (frame->GetByteCount() / RGBA8888_PIXEL_BYTES) * RGB888_PIXEL_BYTES;
505 uint8_t *rgb888 = new uint8_t[rgb888Size];
506 const uint32_t *rgba8888Data = reinterpret_cast<const uint32_t *>(frame->GetPixels());
507 auto ret = RGBA8888ToRGB888(rgba8888Data, frame->GetByteCount() / RGBA8888_PIXEL_BYTES, rgb888, rgb888Size);
508 if (ret) {
509 HILOG_DEBUG("snapshot: convert rgba8888 to rgb888 successfully.");
510 WriteRgb888ToJpeg(fileName, frame->GetWidth(), frame->GetHeight(), rgb888);
511 }
512 delete [] rgb888;
513 }
514 #endif
515 } // namespace AAFwk
516 } // namespace OHOS
517