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 API_CORE_IMAGE_IIMAGE_LOADER_MANAGER_H
17 #define API_CORE_IMAGE_IIMAGE_LOADER_MANAGER_H
18 
19 #include <cstdint>
20 
21 #include <base/containers/string.h>
22 #include <base/containers/string_view.h>
23 #include <base/containers/unique_ptr.h>
24 #include <base/containers/vector.h>
25 #include <base/namespace.h>
26 #include <core/image/intf_animated_image.h>
27 #include <core/image/intf_image_container.h>
28 #include <core/namespace.h>
29 #include <core/plugin/intf_plugin.h>
30 
31 BASE_BEGIN_NAMESPACE()
32 template<class T>
33 class array_view;
34 BASE_END_NAMESPACE()
35 
36 CORE_BEGIN_NAMESPACE()
37 class IFile;
38 const int MAX_ERR_MSG_LEN = 128;
39 
40 // NOTE: Nicer way to return error strings.
41 /** @ingroup group_image_iimagemanager */
42 /** IImage manager */
43 class IImageLoaderManager {
44 public:
45     /** Describes result of the loading operation. */
46     struct LoadResult {
47         /** Load result was successful? */
48         bool success { false };
49         /** Load result error message if load was not successful. */
50         char error[MAX_ERR_MSG_LEN];
51 
52         /** Pointer to image container */
53         IImageContainer::Ptr image;
54     };
55 
56     /** Describes result of the animation loading operation. */
57     struct LoadAnimatedResult {
58         /** Load result was successful? */
59         bool success { false };
60         /** Load result error message if load was not successful. */
61         char error[MAX_ERR_MSG_LEN];
62 
63         /** Pointer to image container */
64         IAnimatedImage::Ptr image;
65     };
66 
67     /** Describes supported format. */
68     struct ImageType {
69         /** Media type (Multipurpose Internet Mail Extensions or MIME). */
70         BASE_NS::string mimeType;
71         /** File extension typically used for this media type. */
72         BASE_NS::string fileExtension;
73     };
74 
75     /** Image loader flags */
76     enum ImageLoaderFlags : uint32_t {
77         /** Generate mipmaps if not already included in the image file. */
78         IMAGE_LOADER_GENERATE_MIPS = 0x00000001,
79         /** Force linear RGB. */
80         IMAGE_LOADER_FORCE_LINEAR_RGB_BIT = 0x00000002,
81         /** Force SRGB. */
82         IMAGE_LOADER_FORCE_SRGB_BIT = 0x00000004,
83         /** Force grayscale. */
84         IMAGE_LOADER_FORCE_GRAYSCALE_BIT = 0x00000008,
85         /** Flip image vertically when loaded. */
86         IMAGE_LOADER_FLIP_VERTICALLY_BIT = 0x00000010,
87         /** Premultiply color values with the alpha value if an alpha channel is present. */
88         IMAGE_LOADER_PREMULTIPLY_ALPHA = 0x00000020,
89         /** Only load image metadata (size and format) */
90         IMAGE_LOADER_METADATA_ONLY = 0x00000040,
91     };
92 
93     /** Interface for defining loaders for different image formats. */
94     class IImageLoader {
95     public:
96         /** Detect whether current loader can load given image
97          * @param imageFileBytes Image data.
98          * @return True if this loader supports the image format.
99          */
100         virtual bool CanLoad(BASE_NS::array_view<const uint8_t> imageFileBytes) const = 0;
101 
102         /** Load Image file from provided file with passed flags
103          * @param file File where to load from
104          * @param loadFlags Load flags. Combination of #ImageLoaderFlags
105          * @return Result of the loading operation.
106          */
107         virtual LoadResult Load(IFile& file, uint32_t loadFlags) const = 0;
108 
109         /** Load image file from given data bytes
110          * @param imageFileBytes Image data.
111          * @param loadFlags Load flags. Combination of #ImageLoaderFlags
112          * @return Result of the loading operation.
113          */
114         virtual LoadResult Load(BASE_NS::array_view<const uint8_t> imageFileBytes, uint32_t loadFlags) const = 0;
115 
116         /** Load animated image with given parameters
117          * @param file File to load image from
118          * @param loadFlags Load flags. Combination of #ImageLoaderFlags
119          * @return Result of the loading operation.
120          */
121         virtual LoadAnimatedResult LoadAnimatedImage(IFile& file, uint32_t loadFlags) = 0;
122 
123         /** Load animated image with given parameters
124          * @param imageFileBytes Image data
125          * @param loadFlags Load flags. Combination of #ImageLoaderFlags
126          * @return Result of the loading operation.
127          */
128         virtual LoadAnimatedResult LoadAnimatedImage(
129             BASE_NS::array_view<const uint8_t> imageFileBytes, uint32_t loadFlags) = 0;
130 
131         /** Return a list of supported image formats.
132          * @return List of supported image formats.
133          */
134         virtual BASE_NS::vector<ImageType> GetSupportedTypes() const = 0;
135 
136         struct Deleter {
137             constexpr Deleter() noexcept = default;
operatorDeleter138             void operator()(IImageLoader* ptr) const
139             {
140                 ptr->Destroy();
141             }
142         };
143         using Ptr = BASE_NS::unique_ptr<IImageLoader, Deleter>;
144 
145     protected:
146         IImageLoader() = default;
147         virtual ~IImageLoader() = default;
148         virtual void Destroy() = 0;
149     };
150 
151     /** Information needed from the plugin for managing ImageLoaders. */
152     struct ImageLoaderTypeInfo : public ITypeInfo {
153         /** TypeInfo UID for image loader type info. */
154         static constexpr BASE_NS::Uid UID { "d6846818-5083-43fc-b9ff-28905a2b4ae2" };
155 
156         using CreateLoaderFn = IImageLoader::Ptr (*)(PluginToken);
157         /* Token passed to loader creation (e.g. plugin specific data). */
158         const PluginToken token;
159         /** Unique ID of the image loader. */
160         const BASE_NS::Uid uid;
161         /** Pointer to function which is used to create loader instances. */
162         const CreateLoaderFn createLoader;
163         /** List of formats the loader supports. */
164         const BASE_NS::array_view<const ImageType> imageTypes;
165     };
166 
167     // Prevent copy construction and assign.
168     IImageLoaderManager(IImageLoaderManager const&) = delete;
169     IImageLoaderManager& operator=(IImageLoaderManager const&) = delete;
170 
171     /** Register image loader for image manager
172      * @param imageLoader Image loader to be registered
173      */
174     [[deprecated("Use IPluginRegister::Register/UnregisterTypeInfo with ImageLoaderTypeInfo.")]] virtual void
175     RegisterImageLoader(IImageLoader::Ptr imageLoader) = 0;
176 
177     /** Load image with given parameters
178      * @param uri Uri to image
179      * @param loadFlags Load flags. Combination of #ImageLoaderFlags
180      */
181     virtual LoadResult LoadImage(const BASE_NS::string_view uri, uint32_t loadFlags) = 0;
182 
183     /** Load image with given parameters
184      * @param file File to load image from
185      * @param loadFlags Load flags. Combination of #ImageLoaderFlags
186      */
187     virtual LoadResult LoadImage(IFile& file, uint32_t loadFlags) = 0;
188 
189     /** Load image with given parameters
190      * @param imageFileBytes Image data
191      * @param loadFlags Load flags. Combination of #ImageLoaderFlags
192      */
193     virtual LoadResult LoadImage(BASE_NS::array_view<const uint8_t> imageFileBytes, uint32_t loadFlags) = 0;
194 
195     /** Load animated image with given parameters
196      * @param uri Uri to image
197      * @param loadFlags Load flags. Combination of #ImageLoaderFlags
198      */
199     virtual LoadAnimatedResult LoadAnimatedImage(const BASE_NS::string_view uri, uint32_t loadFlags) = 0;
200 
201     /** Load animated image with given parameters
202      * @param file File to load image from
203      * @param loadFlags Load flags. Combination of #ImageLoaderFlags
204      */
205     virtual LoadAnimatedResult LoadAnimatedImage(IFile& file, uint32_t loadFlags) = 0;
206 
207     /** Load animated image with given parameters
208      * @param imageFileBytes Image data
209      * @param loadFlags Load flags. Combination of #ImageLoaderFlags
210      */
211     virtual LoadAnimatedResult LoadAnimatedImage(
212         BASE_NS::array_view<const uint8_t> imageFileBytes, uint32_t loadFlags) = 0;
213 
214     /** Return a list of supported image formats.
215      * @return List of supported image formats.
216      */
217     virtual BASE_NS::vector<ImageType> GetSupportedTypes() const = 0;
218 
219 protected:
220     IImageLoaderManager() = default;
221     virtual ~IImageLoaderManager() = default;
222 };
223 CORE_END_NAMESPACE()
224 
225 #endif // API_CORE_IMAGE_IIMAGE_LOADER_MANAGER_H
226