1 /*
2  * Copyright (C) 2024 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 #ifndef FRAMEWORKS_SERVICES_THUMBNAIL_SOURCE_LOADING_H
17 #define FRAMEWORKS_SERVICES_THUMBNAIL_SOURCE_LOADING_H
18 
19 #include <unordered_map>
20 
21 #include "image_packer.h"
22 #include "media_log.h"
23 #include "medialibrary_errno.h"
24 #include "thumbnail_const.h"
25 #include "thumbnail_data.h"
26 
27 namespace OHOS {
28 namespace Media {
29 #define EXPORT __attribute__ ((visibility ("default")))
30 
31 EXPORT std::string GetLocalThumbnailPath(const std::string &path, const std::string &key);
32 EXPORT Size ConvertDecodeSize(ThumbnailData &data, const Size &sourceSize, Size &desiredSize);
33 EXPORT bool GenDecodeOpts(const Size &sourceSize, const Size &targetSize, DecodeOptions &decodeOpts);
34 EXPORT std::unique_ptr<ImageSource> LoadImageSource(const std::string &path, uint32_t &err);
35 EXPORT bool NeedAutoResize(const Size &size);
36 
37 const std::unordered_map<SourceState, std::string> STATE_NAME_MAP = {
38     { SourceState::BEGIN, "BEGIN" },
39     { SourceState::LOCAL_THUMB, "LOCAL_THUMB" },
40     { SourceState::LOCAL_LCD, "LOCAL_LCD" },
41     { SourceState::LOCAL_ORIGIN, "LOCAL_ORIGIN" },
42     { SourceState::CLOUD_THUMB, "CLOUD_THUMB" },
43     { SourceState::CLOUD_LCD, "CLOUD_LCD" },
44     { SourceState::CLOUD_ORIGIN, "CLOUD_ORIGIN" },
45     { SourceState::ERROR, "ERROR" },
46     { SourceState::FINISH, "FINISH" },
47 };
48 
49 class BeginSource {
50 public:
GetSourcePath(ThumbnailData & data,int32_t & error)51     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error)
52         { return ""; }
IsSizeLargeEnough(ThumbnailData & data,int32_t & minSize)53     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize) { return false; }
54 };
55 
56 class LocalThumbSource {
57 public:
58     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error);
59     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize);
60 };
61 
62 class LocalLcdSource {
63 public:
64     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error);
65     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize);
66 };
67 
68 class LocalOriginSource {
69 public:
70     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error);
71     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize);
72 };
73 
74 class CloudThumbSource {
75 public:
76     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error);
77     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize);
78 };
79 
80 class CloudLcdSource {
81 public:
82     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error);
83     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize);
84 };
85 
86 class CloudOriginSource {
87 public:
88     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error);
89     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize);
90 };
91 
92 class ErrorSource {
93 public:
GetSourcePath(ThumbnailData & data,int32_t & error)94     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error)
95         { return ""; }
IsSizeLargeEnough(ThumbnailData & data,int32_t & minSize)96     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize) { return false; }
97 };
98 
99 class FinishSource {
100 public:
GetSourcePath(ThumbnailData & data,int32_t & error)101     EXPORT static std::string GetSourcePath(ThumbnailData &data, int32_t &error)
102         { return ""; }
IsSizeLargeEnough(ThumbnailData & data,int32_t & minSize)103     EXPORT static bool IsSizeLargeEnough(ThumbnailData &data, int32_t &minSize) { return false; }
104 };
105 
106 struct StateFunc {
107     std::string (*GetSourcePath)(ThumbnailData &data, int32_t &error);
108     bool (*IsSizeLargeEnough)(ThumbnailData &data, int32_t &minSize);
109 };
110 
111 const std::unordered_map<SourceState, StateFunc> STATE_FUNC_MAP = {
112     { SourceState::BEGIN, { BeginSource::GetSourcePath, BeginSource::IsSizeLargeEnough } },
113     { SourceState::LOCAL_THUMB, { LocalThumbSource::GetSourcePath, LocalThumbSource::IsSizeLargeEnough } },
114     { SourceState::LOCAL_LCD, { LocalLcdSource::GetSourcePath, LocalLcdSource::IsSizeLargeEnough } },
115     { SourceState::LOCAL_ORIGIN, { LocalOriginSource::GetSourcePath, LocalOriginSource::IsSizeLargeEnough } },
116     { SourceState::CLOUD_THUMB, { CloudThumbSource::GetSourcePath, CloudThumbSource::IsSizeLargeEnough } },
117     { SourceState::CLOUD_LCD, { CloudLcdSource::GetSourcePath, CloudLcdSource::IsSizeLargeEnough } },
118     { SourceState::CLOUD_ORIGIN, { CloudOriginSource::GetSourcePath, CloudOriginSource::IsSizeLargeEnough } },
119     { SourceState::ERROR, { ErrorSource::GetSourcePath, ErrorSource::IsSizeLargeEnough } },
120     { SourceState::FINISH, { FinishSource::GetSourcePath, FinishSource::IsSizeLargeEnough } },
121 };
122 
123 class SourceLoader {
124 public:
125     /*
126      * Define source loading states sequence for creating thumbnails from local photo.
127      */
128     static const std::unordered_map<SourceState, SourceState> LOCAL_SOURCE_LOADING_STATES;
129 
130     /*
131      * Define source loading states sequence for creating thumbnails from cloud photo.
132      */
133     static const std::unordered_map<SourceState, SourceState> CLOUD_SOURCE_LOADING_STATES;
134 
135     /*
136      * Define source loading states sequence for creating thumbnails on demand.
137      */
138     static const std::unordered_map<SourceState, SourceState> ALL_SOURCE_LOADING_STATES;
139 
140     /*
141      * Define source loading states sequence for creating cloud video thumbnails on demand.
142      */
143     static const std::unordered_map<SourceState, SourceState> ALL_SOURCE_LOADING_CLOUD_VIDEO_STATES;
144 
145     /*
146      * Define source loading states sequence for creating thumbnails resolved cloud LCD.
147      */
148     static const std::unordered_map<SourceState, SourceState> CLOUD_LCD_SOURCE_LOADING_STATES;
149 
150     /*
151      * Define source loading states sequence for creating thumbnails resolved local LCD.
152      */
153     static const std::unordered_map<SourceState, SourceState> LOCAL_LCD_SOURCE_LOADING_STATES;
154 
155     /*
156      * Define source loading states sequence for upgrading thumbnails.
157      */
158     static const std::unordered_map<SourceState, SourceState> UPGRADE_SOURCE_LOADING_STATES;
159 
160     /*
161      * Define source loading states sequence for upgrading video thumbnails.
162      */
163     static const std::unordered_map<SourceState, SourceState> UPGRADE_VIDEO_SOURCE_LOADING_STATES;
164 
SourceLoader(Size & desiredSize,ThumbnailData & data)165     SourceLoader(Size &desiredSize, ThumbnailData &data) : data_(data), desiredSize_(desiredSize)
166     {
167         GetSourcePath = nullptr;
168         IsSizeLargeEnough = nullptr;
169     };
170     ~SourceLoader() = default;
171     bool RunLoading();
172 
173 private:
174     void SetCurrentStateFunction();
175     bool IsSizeAcceptable(std::unique_ptr<ImageSource>& imageSource, ImageInfo& imageInfo);
176     bool CreateSourcePixelMap();
177     bool CreateImagePixelMap(const std::string &sourcePath);
178     bool CreateVideoFramePixelMap();
179     bool GeneratePictureSource(std::unique_ptr<ImageSource> &imageSource, const Size &targetSize);
180     bool GeneratePixelMapSource(std::unique_ptr<ImageSource> &imageSource, const Size &sourceSize,
181         const Size &targetSize);
182 
183     bool IsFinal();
184 
185     int32_t error_ { E_OK };
186     std::string (*GetSourcePath)(ThumbnailData &data, int32_t &error);
187     bool (*IsSizeLargeEnough)(ThumbnailData &data, int32_t &minSize);
188 
189     ThumbnailData &data_;
190     Size &desiredSize_;
191     SourceState state_ { SourceState::BEGIN };
192 };
193 
194 } // namespace Media
195 } // namespace OHOS
196 
197 #endif // FRAMEWORKS_SERVICES_THUMBNAIL_SOURCE_LOADING_H