• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cstdio>
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 = static_cast<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 
LoadAllMissionInfo(std::list<InnerMissionInfo> & missionInfoList)80 bool MissionDataStorage::LoadAllMissionInfo(std::list<InnerMissionInfo> &missionInfoList)
81 {
82     std::vector<std::string> fileNameVec;
83     std::vector<int32_t> tempMissions;
84     std::string dirPath = GetMissionDataDirPath();
85     OHOS::GetDirFiles(dirPath, fileNameVec);
86 
87     for (auto fileName : fileNameVec) {
88         if (!CheckFileNameValid(fileName)) {
89             HILOG_ERROR("load mission info: file name %{public}s invalid.", fileName.c_str());
90             continue;
91         }
92 
93         std::string content;
94         bool loadFile = OHOS::LoadStringFromFile(fileName, content);
95         if (!loadFile) {
96             HILOG_ERROR("load string from file %{public}s failed.", fileName.c_str());
97             continue;
98         }
99 
100         InnerMissionInfo misssionInfo;
101         if (!misssionInfo.FromJsonStr(content)) {
102             HILOG_ERROR("parse mission info failed. file: %{public}s", fileName.c_str());
103             continue;
104         }
105         if (misssionInfo.isTemporary) {
106             tempMissions.push_back(misssionInfo.missionInfo.id);
107             continue;
108         }
109         missionInfoList.push_back(misssionInfo);
110     }
111 
112     for (auto missionId : tempMissions) {
113         DeleteMissionInfo(missionId);
114     }
115     return true;
116 }
117 
SaveMissionInfo(const InnerMissionInfo & missionInfo)118 void MissionDataStorage::SaveMissionInfo(const InnerMissionInfo &missionInfo)
119 {
120     std::string filePath = GetMissionDataFilePath(missionInfo.missionInfo.id);
121     std::string dirPath = OHOS::ExtractFilePath(filePath);
122     if (!OHOS::FileExists(dirPath)) {
123         bool createDir = OHOS::ForceCreateDirectory(dirPath);
124         if (!createDir) {
125             HILOG_ERROR("create dir %{public}s failed.", dirPath.c_str());
126             return;
127         }
128         chmod(dirPath.c_str(), MODE);
129     }
130 
131     std::string jsonStr = missionInfo.ToJsonStr();
132     bool saveMissionFile = OHOS::SaveStringToFile(filePath, jsonStr, true);
133     if (!saveMissionFile) {
134         HILOG_ERROR("save mission file %{public}s failed.", filePath.c_str());
135     }
136 }
137 
DeleteMissionInfo(int missionId)138 void MissionDataStorage::DeleteMissionInfo(int missionId)
139 {
140     std::string filePath = GetMissionDataFilePath(missionId);
141     bool removeMissionFile = OHOS::RemoveFile(filePath);
142     if (!removeMissionFile) {
143         HILOG_ERROR("remove mission file %{public}s failed.", filePath.c_str());
144         return;
145     }
146     DeleteMissionSnapshot(missionId);
147 }
148 
SaveMissionSnapshot(int32_t missionId,const MissionSnapshot & missionSnapshot)149 void MissionDataStorage::SaveMissionSnapshot(int32_t missionId, const MissionSnapshot& missionSnapshot)
150 {
151 #ifdef SUPPORT_GRAPHICS
152     HILOG_INFO("snapshot: save snapshot from cache, missionId = %{public}d", missionId);
153     SaveCachedSnapshot(missionId, missionSnapshot);
154     SaveSnapshotFile(missionId, missionSnapshot);
155     HILOG_INFO("snapshot: delete snapshot from cache, missionId = %{public}d", missionId);
156     DeleteCachedSnapshot(missionId);
157 #endif
158 }
159 
DeleteMissionSnapshot(int32_t missionId)160 void MissionDataStorage::DeleteMissionSnapshot(int32_t missionId)
161 {
162 #ifdef SUPPORT_GRAPHICS
163     DeleteMissionSnapshot(missionId, false);
164     DeleteMissionSnapshot(missionId, true);
165 #endif
166 }
167 
GetMissionSnapshot(int32_t missionId,MissionSnapshot & missionSnapshot,bool isLowResolution)168 bool MissionDataStorage::GetMissionSnapshot(int32_t missionId, MissionSnapshot& missionSnapshot, bool isLowResolution)
169 {
170 #ifdef SUPPORT_GRAPHICS
171     if (GetCachedSnapshot(missionId, missionSnapshot)) {
172         if (isLowResolution) {
173             missionSnapshot.snapshot = GetReducedPixelMap(missionSnapshot.snapshot);
174         }
175         HILOG_INFO("snapshot: GetMissionSnapshot from cache, missionId = %{public}d", missionId);
176         return true;
177     }
178 
179     auto pixelMap = GetPixelMap(missionId, isLowResolution);
180     if (!pixelMap) {
181         HILOG_ERROR("%{public}s: GetPixelMap failed.", __func__);
182         return false;
183     }
184     missionSnapshot.snapshot = std::move(pixelMap);
185 #endif
186     return true;
187 }
188 
GetMissionDataDirPath() const189 std::string MissionDataStorage::GetMissionDataDirPath() const
190 {
191     return std::string(TASK_DATA_FILE_BASE_PATH) + "/" + std::to_string(userId_) + "/"
192         + std::string(MISSION_DATA_FILE_PATH);
193 }
194 
GetMissionDataFilePath(int missionId)195 std::string MissionDataStorage::GetMissionDataFilePath(int missionId)
196 {
197     return GetMissionDataDirPath() + "/"
198         + MISSION_JSON_FILE_PREFIX + "_" + std::to_string(missionId) + JSON_FILE_SUFFIX;
199 }
200 
GetMissionSnapshotPath(int32_t missionId,bool isLowResolution) const201 std::string MissionDataStorage::GetMissionSnapshotPath(int32_t missionId, bool isLowResolution) const
202 {
203     std::string filePath = GetMissionDataDirPath() + FILE_SEPARATOR + MISSION_JSON_FILE_PREFIX +
204         UNDERLINE_SEPARATOR + std::to_string(missionId);
205     if (isLowResolution) {
206         filePath = filePath + UNDERLINE_SEPARATOR + LOW_RESOLUTION_FLAG;
207     }
208     filePath = filePath + JPEG_FILE_SUFFIX;
209     return filePath;
210 }
211 
CheckFileNameValid(const std::string & fileName)212 bool MissionDataStorage::CheckFileNameValid(const std::string &fileName)
213 {
214     std::string fileNameExcludePath = OHOS::ExtractFileName(fileName);
215     if (fileNameExcludePath.find(MISSION_JSON_FILE_PREFIX) != 0) {
216         return false;
217     }
218 
219     if (fileNameExcludePath.find("_") != std::string(MISSION_JSON_FILE_PREFIX).length()) {
220         return false;
221     }
222 
223     if (fileNameExcludePath.find(JSON_FILE_SUFFIX) != fileNameExcludePath.length()
224         - std::string(JSON_FILE_SUFFIX).length()) {
225         return false;
226     }
227 
228     size_t missionIdLength = fileNameExcludePath.find(JSON_FILE_SUFFIX) - fileNameExcludePath.find("_") - 1;
229     std::string missionId = fileNameExcludePath.substr(fileNameExcludePath.find("_") + 1, missionIdLength);
230     for (auto ch : missionId) {
231         if (!isdigit(ch)) {
232             return false;
233         }
234     }
235 
236     return true;
237 }
238 
239 #ifdef SUPPORT_GRAPHICS
SaveSnapshotFile(int32_t missionId,const MissionSnapshot & missionSnapshot)240 void MissionDataStorage::SaveSnapshotFile(int32_t missionId, const MissionSnapshot& missionSnapshot)
241 {
242     SaveSnapshotFile(missionId, missionSnapshot.snapshot, missionSnapshot.isPrivate, false);
243     SaveSnapshotFile(missionId, GetReducedPixelMap(missionSnapshot.snapshot), missionSnapshot.isPrivate, true);
244     DelayedSingleton<MissionInfoMgr>::GetInstance()->CompleteSaveSnapshot(missionId);
245 }
246 
SaveSnapshotFile(int32_t missionId,const std::shared_ptr<OHOS::Media::PixelMap> & snapshot,bool isPrivate,bool isLowResolution)247 void MissionDataStorage::SaveSnapshotFile(int32_t missionId, const std::shared_ptr<OHOS::Media::PixelMap>& snapshot,
248     bool isPrivate, bool isLowResolution)
249 {
250     if (!snapshot) {
251         return;
252     }
253 
254     std::string filePath = GetMissionSnapshotPath(missionId, isLowResolution);
255     std::string dirPath = OHOS::ExtractFilePath(filePath);
256     if (!OHOS::FileExists(dirPath)) {
257         bool createDir = OHOS::ForceCreateDirectory(dirPath);
258         if (!createDir) {
259             HILOG_ERROR("snapshot: create dir %{public}s failed.", dirPath.c_str());
260             return;
261         }
262         chmod(dirPath.c_str(), MODE);
263     }
264 
265     if (isPrivate) {
266         HILOG_DEBUG("snapshot: the param isPrivate is true.");
267         ssize_t dataLength = snapshot->GetWidth() * snapshot->GetHeight() * RGB888_PIXEL_BYTES;
268         uint8_t* data = (uint8_t*) malloc(dataLength);
269         if (data == nullptr) {
270             HILOG_ERROR("malloc failed.");
271             return;
272         }
273         if (memset_s(data, dataLength, 0xff, dataLength) == EOK) {
274             WriteRgb888ToJpeg(filePath.c_str(), snapshot->GetWidth(), snapshot->GetHeight(), data);
275         }
276         free(data);
277     } else {
278         if (snapshot->GetPixelFormat() == Media::PixelFormat::RGB_565) {
279             SaveRGB565Image(snapshot, filePath.c_str());
280         } else if (snapshot->GetPixelFormat() == Media::PixelFormat::RGBA_8888) {
281             SaveRGBA8888Image(snapshot, filePath.c_str());
282         } else if (snapshot->GetPixelFormat() == Media::PixelFormat::RGB_888) {
283             WriteRgb888ToJpeg(filePath.c_str(), snapshot->GetWidth(), snapshot->GetHeight(), snapshot->GetPixels());
284         } else {
285             HILOG_ERROR("snapshot: invalid pixel format.");
286         }
287     }
288 }
289 
GetReducedPixelMap(const std::shared_ptr<OHOS::Media::PixelMap> & snapshot)290 std::shared_ptr<OHOS::Media::PixelMap> MissionDataStorage::GetReducedPixelMap(
291     const std::shared_ptr<OHOS::Media::PixelMap>& snapshot)
292 {
293     if (!snapshot) {
294         return nullptr;
295     }
296 
297     OHOS::Media::InitializationOptions options;
298     options.size.width = snapshot->GetWidth() / SCALE;
299     options.size.height = snapshot->GetHeight() / SCALE;
300     std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*snapshot, options);
301     return std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
302 }
303 
GetCachedSnapshot(int32_t missionId,MissionSnapshot & missionSnapshot)304 bool MissionDataStorage::GetCachedSnapshot(int32_t missionId, MissionSnapshot& missionSnapshot)
305 {
306     std::lock_guard<ffrt::mutex> lock(cachedPixelMapMutex_);
307     auto pixelMap = cachedPixelMap_.find(missionId);
308     if (pixelMap != cachedPixelMap_.end()) {
309         missionSnapshot.snapshot = pixelMap->second;
310         return true;
311     }
312     return false;
313 }
314 
SaveCachedSnapshot(int32_t missionId,const MissionSnapshot & missionSnapshot)315 bool MissionDataStorage::SaveCachedSnapshot(int32_t missionId, const MissionSnapshot& missionSnapshot)
316 {
317     std::lock_guard<ffrt::mutex> lock(cachedPixelMapMutex_);
318     auto result = cachedPixelMap_.insert_or_assign(missionId, missionSnapshot.snapshot);
319     if (!result.second) {
320         HILOG_ERROR("snapshot: save snapshot cache failed, missionId = %{public}d", missionId);
321         return false;
322     }
323     return true;
324 }
325 
DeleteCachedSnapshot(int32_t missionId)326 bool MissionDataStorage::DeleteCachedSnapshot(int32_t missionId)
327 {
328     std::lock_guard<ffrt::mutex> lock(cachedPixelMapMutex_);
329     auto result = cachedPixelMap_.erase(missionId);
330     if (result != 1) {
331         HILOG_ERROR("snapshot: delete snapshot cache failed, missionId = %{public}d", missionId);
332         return false;
333     }
334     return true;
335 }
336 
DeleteMissionSnapshot(int32_t missionId,bool isLowResolution)337 void MissionDataStorage::DeleteMissionSnapshot(int32_t missionId, bool isLowResolution)
338 {
339     std::string filePath = GetMissionSnapshotPath(missionId, isLowResolution);
340     std::string dirPath = OHOS::ExtractFilePath(filePath);
341     if (!OHOS::FileExists(filePath)) {
342         HILOG_WARN("snapshot: remove snapshot file %{public}s failed, file not exists", filePath.c_str());
343         return;
344     }
345     bool removeResult = OHOS::RemoveFile(filePath);
346     if (!removeResult) {
347         HILOG_ERROR("snapshot: remove snapshot file %{public}s failed.", filePath.c_str());
348     }
349 }
350 
GetSnapshot(int missionId,bool isLowResolution) const351 std::shared_ptr<Media::PixelMap> MissionDataStorage::GetSnapshot(int missionId, bool isLowResolution) const
352 {
353     auto pixelMapPtr = GetPixelMap(missionId, isLowResolution);
354     if (!pixelMapPtr) {
355         HILOG_ERROR("%{public}s: GetPixelMap failed.", __func__);
356         return nullptr;
357     }
358     return std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
359 }
360 
ReadFileToBuffer(const std::string & filePath,size_t & bufferSize) const361 std::unique_ptr<uint8_t[]> MissionDataStorage::ReadFileToBuffer(const std::string &filePath, size_t &bufferSize) const
362 {
363     struct stat statbuf;
364     int ret = stat(filePath.c_str(), &statbuf);
365     if (ret != 0) {
366         HILOG_ERROR("GetPixelMap: get the file size failed, ret:%{public}d.", ret);
367         return nullptr;
368     }
369     bufferSize = static_cast<size_t>(statbuf.st_size);
370     std::string realPath;
371     if (!OHOS::PathToRealPath(filePath, realPath)) {
372         HILOG_ERROR("ReadFileToBuffer:file path to real path failed, file path=%{public}s.", filePath.c_str());
373         return nullptr;
374     }
375 
376     std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(bufferSize);
377     if (buffer == nullptr) {
378         HILOG_ERROR("ReadFileToBuffer:buffer is nullptr");
379         return nullptr;
380     }
381 
382     FILE *fp = fopen(realPath.c_str(), "rb");
383     if (fp == nullptr) {
384         HILOG_ERROR("ReadFileToBuffer:open file failed, real path=%{public}s.", realPath.c_str());
385         return nullptr;
386     }
387     fseek(fp, 0, SEEK_END);
388     size_t fileSize = static_cast<size_t>(ftell(fp));
389     fseek(fp, 0, SEEK_SET);
390     if (bufferSize < fileSize) {
391         HILOG_ERROR("ReadFileToBuffer:buffer size:(%{public}zu) is smaller than file size:(%{public}zu).", bufferSize,
392             fileSize);
393         fclose(fp);
394         return nullptr;
395     }
396     size_t retSize = std::fread(buffer.get(), 1, fileSize, fp);
397     if (retSize != fileSize) {
398         HILOG_ERROR("ReadFileToBuffer:read file result size = %{public}zu, size = %{public}zu.", retSize, fileSize);
399         fclose(fp);
400         return nullptr;
401     }
402     fclose(fp);
403     return buffer;
404 }
405 
GetPixelMap(int missionId,bool isLowResolution) const406 std::unique_ptr<Media::PixelMap> MissionDataStorage::GetPixelMap(int missionId, bool isLowResolution) const
407 {
408     std::string filePath = GetMissionSnapshotPath(missionId, isLowResolution);
409     if (!OHOS::FileExists(filePath)) {
410         HILOG_INFO("snapshot: storage snapshot not exists, missionId = %{public}d", missionId);
411         return nullptr;
412     }
413     uint32_t errCode = 0;
414 
415     size_t bufferSize = 0;
416     const std::string fileName = filePath;
417     std::unique_ptr<uint8_t[]> buffer = MissionDataStorage::ReadFileToBuffer(fileName, bufferSize);
418     if (buffer == nullptr) {
419         HILOG_ERROR("GetPixelMap: get buffer error buffer == nullptr");
420         return nullptr;
421     }
422     Media::SourceOptions sourceOptions;
423     auto imageSource = Media::ImageSource::CreateImageSource(buffer.get(), bufferSize, sourceOptions, errCode);
424     if (errCode != OHOS::Media::SUCCESS || imageSource == nullptr) {
425         HILOG_ERROR("snapshot: CreateImageSource failed, nullptr or errCode = %{public}d", errCode);
426         return nullptr;
427     }
428     Media::DecodeOptions decodeOptions;
429     decodeOptions.allocatorType = Media::AllocatorType::SHARE_MEM_ALLOC;
430     auto pixelMapPtr = imageSource->CreatePixelMap(decodeOptions, errCode);
431     if (errCode != OHOS::Media::SUCCESS) {
432         HILOG_ERROR("snapshot: CreatePixelMap failed, errCode = %{public}d", errCode);
433         return nullptr;
434     }
435     return pixelMapPtr;
436 }
437 
WriteRgb888ToJpeg(const char * fileName,uint32_t width,uint32_t height,const uint8_t * data)438 void MissionDataStorage::WriteRgb888ToJpeg(const char* fileName, uint32_t width, uint32_t height, const uint8_t* data)
439 {
440     HILOG_INFO("file:%{public}s", fileName);
441     if (data == nullptr) {
442         HILOG_ERROR("snapshot: data error, nullptr!\n");
443         return;
444     }
445 
446     FILE *file = fopen(fileName, "wb");
447     if (file == nullptr) {
448         HILOG_ERROR("snapshot: open file [%s] error, nullptr!\n", fileName);
449         return;
450     }
451 
452     struct jpeg_compress_struct jpeg;
453     struct mission_error_mgr jerr;
454     jpeg.err = jpeg_std_error(&jerr);
455     jerr.error_exit = mission_error_exit;
456     if (setjmp(jerr.environment)) {
457         jpeg_destroy_compress(&jpeg);
458         (void)fclose(file);
459         file = nullptr;
460         HILOG_ERROR("snapshot: lib jpeg exit with error!");
461         return;
462     }
463 
464     jpeg_create_compress(&jpeg);
465     jpeg.image_width = width;
466     jpeg.image_height = height;
467     jpeg.input_components = RGB888_PIXEL_BYTES;
468     jpeg.in_color_space = JCS_RGB;
469     jpeg_set_defaults(&jpeg);
470 
471     constexpr int32_t quality = 75;
472     jpeg_set_quality(&jpeg, quality, TRUE);
473 
474     jpeg_stdio_dest(&jpeg, file);
475     jpeg_start_compress(&jpeg, TRUE);
476     JSAMPROW rowPointer[1];
477     for (uint32_t i = 0; i < jpeg.image_height; i++) {
478         rowPointer[0] = const_cast<uint8_t *>(data + i * jpeg.image_width * RGB888_PIXEL_BYTES);
479         (void)jpeg_write_scanlines(&jpeg, rowPointer, 1);
480     }
481 
482     jpeg_finish_compress(&jpeg);
483     (void)fclose(file);
484     file = nullptr;
485     jpeg_destroy_compress(&jpeg);
486 }
487 
488 // only valid for little-endian order.
RGB565ToRGB888(const uint16_t * rgb565Buf,int32_t rgb565Size,uint8_t * rgb888Buf,int32_t rgb888Size)489 bool MissionDataStorage::RGB565ToRGB888(const uint16_t *rgb565Buf, int32_t rgb565Size,
490     uint8_t *rgb888Buf, int32_t rgb888Size)
491 {
492     if (rgb565Buf == nullptr || rgb565Size <= 0 || rgb888Buf == nullptr || rgb888Size <= 0) {
493         HILOG_ERROR("%{public}s: params are invalid.", __func__);
494         return false;
495     }
496 
497     if (rgb888Size < rgb565Size * RGB888_PIXEL_BYTES) {
498         HILOG_ERROR("%{public}s: rgb888Size are invalid.", __func__);
499         return false;
500     }
501 
502     for (int32_t i = 0; i < rgb565Size; i++) {
503         rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] = (rgb565Buf[i] & RGB565_MASK_RED);
504         rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] = (rgb565Buf[i] & RGB565_MASK_GREEN) >> SHIFT_5_BIT;
505         rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] = (rgb565Buf[i] & RGB565_MASK_BLUE) >> SHIFT_11_BIT;
506         rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] <<= SHITF_3_BIT;
507         rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] <<= SHIFT_2_BIT;
508         rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] <<= SHITF_3_BIT;
509     }
510 
511     return true;
512 }
513 
RGBA8888ToRGB888(const uint32_t * rgba8888Buf,int32_t rgba8888Size,uint8_t * rgb888Buf,int32_t rgb888Size)514 bool MissionDataStorage::RGBA8888ToRGB888(const uint32_t *rgba8888Buf, int32_t rgba8888Size,
515     uint8_t *rgb888Buf, int32_t rgb888Size)
516 {
517     if (rgba8888Buf == nullptr || rgba8888Size <= 0 || rgb888Buf == nullptr || rgb888Size <= 0) {
518         HILOG_ERROR("%{public}s: params are invalid.", __func__);
519         return false;
520     }
521 
522     if (rgb888Size < rgba8888Size * RGB888_PIXEL_BYTES) {
523         HILOG_ERROR("%{public}s: rgb888Size are invalid.", __func__);
524         return false;
525     }
526 
527     for (int32_t i = 0; i < rgba8888Size; i++) {
528         rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] = (rgba8888Buf[i] & RGBA8888_MASK_RED) >> SHIFT_16_BIT;
529         rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] = (rgba8888Buf[i] & RGBA8888_MASK_GREEN) >> SHIFT_8_BIT;
530         rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] = rgba8888Buf[i] & RGBA8888_MASK_BLUE;
531     }
532 
533     return true;
534 }
535 
SaveRGB565Image(const std::shared_ptr<Media::PixelMap> & frame,const char * fileName)536 void MissionDataStorage::SaveRGB565Image(const std::shared_ptr<Media::PixelMap> &frame, const char* fileName)
537 {
538     HILOG_DEBUG("%{public}s was called.", __func__);
539     int32_t rgb888Size = (frame->GetByteCount() / RGB565_PIXEL_BYTES) * RGB888_PIXEL_BYTES;
540     uint8_t *rgb888 = new uint8_t[rgb888Size];
541     const uint16_t *rgb565Data = reinterpret_cast<const uint16_t *>(frame->GetPixels());
542     auto ret = RGB565ToRGB888(rgb565Data, frame->GetByteCount() / RGB565_PIXEL_BYTES, rgb888, rgb888Size);
543     if (ret) {
544         HILOG_DEBUG("snapshot: convert rgb565 to rgb888 successfully.");
545         WriteRgb888ToJpeg(fileName, frame->GetWidth(), frame->GetHeight(), rgb888);
546     }
547     delete [] rgb888;
548 }
549 
SaveRGBA8888Image(const std::shared_ptr<Media::PixelMap> & frame,const char * fileName)550 void MissionDataStorage::SaveRGBA8888Image(const std::shared_ptr<Media::PixelMap> &frame, const char* fileName)
551 {
552     HILOG_DEBUG("%{public}s was called.", __func__);
553     int32_t rgb888Size = (frame->GetByteCount() / RGBA8888_PIXEL_BYTES) * RGB888_PIXEL_BYTES;
554     uint8_t *rgb888 = new uint8_t[rgb888Size];
555     const uint32_t *rgba8888Data = reinterpret_cast<const uint32_t *>(frame->GetPixels());
556     auto ret = RGBA8888ToRGB888(rgba8888Data, frame->GetByteCount() / RGBA8888_PIXEL_BYTES, rgb888, rgb888Size);
557     if (ret) {
558         HILOG_DEBUG("snapshot: convert rgba8888 to rgb888 successfully.");
559         WriteRgb888ToJpeg(fileName, frame->GetWidth(), frame->GetHeight(), rgb888);
560     }
561     delete [] rgb888;
562 }
563 #endif
564 }  // namespace AAFwk
565 }  // namespace OHOS
566