• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "image_loader_manager.h"
17 
18 #include <algorithm>
19 
20 #include <base/containers/array_view.h>
21 #include <base/containers/string_view.h>
22 #include <base/containers/type_traits.h>
23 #include <base/containers/unique_ptr.h>
24 #include <base/containers/vector.h>
25 #include <base/namespace.h>
26 #include <base/util/uid_util.h>
27 #include <core/image/intf_animated_image.h>
28 #include <core/image/intf_image_container.h>
29 #include <core/image/intf_image_loader_manager.h>
30 #include <core/io/intf_file.h>
31 #include <core/io/intf_file_manager.h>
32 #include <core/log.h>
33 #include <core/namespace.h>
34 #include <core/perf/cpu_perf_scope.h>
35 
36 CORE_BEGIN_NAMESPACE()
37 using BASE_NS::array_view;
38 using BASE_NS::make_unique;
39 using BASE_NS::move;
40 using BASE_NS::string_view;
41 using BASE_NS::unique_ptr;
42 using BASE_NS::vector;
43 
ImageLoaderManager(IFileManager & fileManager)44 ImageLoaderManager::ImageLoaderManager(IFileManager& fileManager) : fileManager_(fileManager)
45 {
46     for (const auto* typeInfo : GetPluginRegister().GetTypeInfos(IImageLoaderManager::ImageLoaderTypeInfo::UID)) {
47         if (typeInfo && (typeInfo->typeUid == IImageLoaderManager::ImageLoaderTypeInfo::UID)) {
48             const auto* imageLoaderInfo = static_cast<const IImageLoaderManager::ImageLoaderTypeInfo*>(typeInfo);
49             if (imageLoaderInfo->createLoader &&
50                 std::none_of(imageLoaders_.cbegin(), imageLoaders_.cend(),
51                     [&uid = imageLoaderInfo->uid](const RegisteredImageLoader& loader) { return loader.uid == uid; })) {
52                 imageLoaders_.push_back(
53                     { imageLoaderInfo->uid, imageLoaderInfo->createLoader(imageLoaderInfo->token) });
54             }
55         }
56     }
57     GetPluginRegister().AddListener(*this);
58 }
59 
~ImageLoaderManager()60 ImageLoaderManager::~ImageLoaderManager()
61 {
62     GetPluginRegister().RemoveListener(*this);
63 }
64 
RegisterImageLoader(IImageLoader::Ptr imageLoader)65 void ImageLoaderManager::RegisterImageLoader(IImageLoader::Ptr imageLoader)
66 {
67     if (!imageLoader) {
68         CORE_LOG_D("imageLoader is null, Not adding.");
69         return;
70     }
71 
72     // NOTE: We just add the registered unique pointers to a vector. The vector is not really used for anything else.
73     // And the loaders cannot be currently unregistered.
74     imageLoaders_.push_back({ {}, move(imageLoader) });
75 }
76 
LoadImage(const string_view uri,uint32_t loadFlags)77 ImageLoaderManager::LoadResult ImageLoaderManager::LoadImage(const string_view uri, uint32_t loadFlags)
78 {
79     CORE_CPU_PERF_SCOPE("CORE", "LoadImage()", uri, CORE_PROFILER_DEFAULT_COLOR);
80 
81     // Load 12 bytes (maximum header size of currently implemented file types)
82     IFile::Ptr file = fileManager_.OpenFile(uri);
83     if (!file) {
84         return ResultFailure("Can not open image.");
85     }
86 
87     return LoadImage(*file, loadFlags);
88 }
89 
LoadImage(IFile & file,uint32_t loadFlags)90 ImageLoaderManager::LoadResult ImageLoaderManager::LoadImage(IFile& file, uint32_t loadFlags)
91 {
92     CORE_CPU_PERF_SCOPE("CORE", "LoadImage(file)", "", CORE_PROFILER_DEFAULT_COLOR);
93 
94     const uint64_t byteLength = 12u;
95 
96     // Read header of the file to a buffer.
97     unique_ptr<uint8_t[]> buffer = make_unique<uint8_t[]>(static_cast<size_t>(byteLength));
98     const uint64_t read = file.Read(buffer.get(), byteLength);
99     if (read != byteLength) {
100         return ResultFailure("Can not read file header.");
101     }
102     file.Seek(0);
103 
104     for (auto& loader : imageLoaders_) {
105         if (loader.instance &&
106             loader.instance->CanLoad(array_view<const uint8_t>(buffer.get(), static_cast<size_t>(byteLength)))) {
107             return loader.instance->Load(file, loadFlags);
108         }
109     }
110     return ResultFailure("Image loader not found for this format.");
111 }
112 
LoadImage(array_view<const uint8_t> imageFileBytes,uint32_t loadFlags)113 ImageLoaderManager::LoadResult ImageLoaderManager::LoadImage(
114     array_view<const uint8_t> imageFileBytes, uint32_t loadFlags)
115 {
116     CORE_CPU_PERF_SCOPE("CORE", "LoadImage(bytes)", "", CORE_PROFILER_DEFAULT_COLOR);
117 
118     for (auto& loader : imageLoaders_) {
119         if (loader.instance && loader.instance->CanLoad(imageFileBytes)) {
120             return loader.instance->Load(imageFileBytes, loadFlags);
121         }
122     }
123 
124     return ResultFailure("Image loader not found for this format.");
125 }
126 
LoadAnimatedImage(const string_view uri,uint32_t loadFlags)127 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::LoadAnimatedImage(const string_view uri, uint32_t loadFlags)
128 {
129     CORE_CPU_PERF_SCOPE("CORE", "LoadAnimatedImage()", uri, CORE_PROFILER_DEFAULT_COLOR);
130 
131     // Load 12 bytes (maximum header size of currently implemented file types)
132     IFile::Ptr file = fileManager_.OpenFile(uri);
133     if (!file) {
134         return ResultFailureAnimated("Can not open image.");
135     }
136 
137     return LoadAnimatedImage(*file, loadFlags);
138 }
139 
LoadAnimatedImage(IFile & file,uint32_t loadFlags)140 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::LoadAnimatedImage(IFile& file, uint32_t loadFlags)
141 {
142     CORE_CPU_PERF_SCOPE("CORE", "LoadAnimatedImage(file)", "", CORE_PROFILER_DEFAULT_COLOR);
143 
144     const uint64_t byteLength = 12u;
145 
146     // Read header of the file to a buffer.
147     unique_ptr<uint8_t[]> buffer = make_unique<uint8_t[]>(static_cast<size_t>(byteLength));
148     const uint64_t read = file.Read(buffer.get(), byteLength);
149     if (read != byteLength) {
150         return ResultFailureAnimated("Can not read file header.");
151     }
152     file.Seek(0);
153 
154     for (auto& loader : imageLoaders_) {
155         if (loader.instance &&
156             loader.instance->CanLoad(array_view<const uint8_t>(buffer.get(), static_cast<size_t>(byteLength)))) {
157             return loader.instance->LoadAnimatedImage(file, loadFlags);
158         }
159     }
160     return ResultFailureAnimated("Image loader not found for this format.");
161 }
162 
LoadAnimatedImage(array_view<const uint8_t> imageFileBytes,uint32_t loadFlags)163 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::LoadAnimatedImage(
164     array_view<const uint8_t> imageFileBytes, uint32_t loadFlags)
165 {
166     CORE_CPU_PERF_SCOPE("CORE", "LoadAnimatedImage(bytes)", "", CORE_PROFILER_DEFAULT_COLOR);
167 
168     for (auto& loader : imageLoaders_) {
169         if (loader.instance && loader.instance->CanLoad(imageFileBytes)) {
170             return loader.instance->LoadAnimatedImage(imageFileBytes, loadFlags);
171         }
172     }
173 
174     return ResultFailureAnimated("Image loader not found for this format.");
175 }
176 
ResultFailure(const string_view error)177 ImageLoaderManager::LoadResult ImageLoaderManager::ResultFailure(const string_view error)
178 {
179     LoadResult result {
180         false,  // if success
181         "",     // array error[128];
182         nullptr // the image;
183     };
184 
185     // Copy the error string
186     const auto count = std::min(error.size(), sizeof(result.error) - 1);
187     error.copy(result.error, count);
188     result.error[count] = '\0';
189 
190     return result;
191 }
192 
ResultSuccess(IImageContainer::Ptr image)193 ImageLoaderManager::LoadResult ImageLoaderManager::ResultSuccess(IImageContainer::Ptr image)
194 {
195     return LoadResult {
196         true,       // if success
197         "",         // array error[128];
198         move(image) // the image;
199     };
200 }
201 
ResultFailureAnimated(const string_view error)202 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::ResultFailureAnimated(const string_view error)
203 {
204     LoadAnimatedResult result {
205         false,  // if success
206         "",     // array error[128];
207         nullptr // the image;
208     };
209 
210     // Copy the error string
211     const auto count = std::min(error.size(), sizeof(result.error) - 1);
212     error.copy(result.error, count);
213     result.error[count] = '\0';
214 
215     return result;
216 }
217 
ResultSuccessAnimated(IAnimatedImage::Ptr image)218 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::ResultSuccessAnimated(IAnimatedImage::Ptr image)
219 {
220     return LoadAnimatedResult {
221         true,       // if success
222         "",         // array error[128];
223         move(image) // the image;
224     };
225 }
226 
GetSupportedTypes() const227 vector<IImageLoaderManager::ImageType> ImageLoaderManager::GetSupportedTypes() const
228 {
229     vector<IImageLoaderManager::ImageType> allTypes;
230     for (const auto& loader : imageLoaders_) {
231         if (loader.instance) {
232             const auto types = loader.instance->GetSupportedTypes();
233             allTypes.append(types.cbegin(), types.cend());
234         } else {
235             CORE_LOG_E(" loader.instance is nullptr and uid: %s", to_string(loader.uid).data());
236         }
237     }
238     return allTypes;
239 }
240 
OnTypeInfoEvent(EventType type,array_view<const ITypeInfo * const> typeInfos)241 void ImageLoaderManager::OnTypeInfoEvent(EventType type, array_view<const ITypeInfo* const> typeInfos)
242 {
243     for (const auto* typeInfo : typeInfos) {
244         if (typeInfo && (typeInfo->typeUid == IImageLoaderManager::ImageLoaderTypeInfo::UID)) {
245             const auto* imageLoaderInfo = static_cast<const IImageLoaderManager::ImageLoaderTypeInfo*>(typeInfo);
246             if (type == EventType::ADDED) {
247                 if (imageLoaderInfo->createLoader &&
248                     std::none_of(imageLoaders_.cbegin(), imageLoaders_.cend(),
249                         [&uid = imageLoaderInfo->uid](
250                             const RegisteredImageLoader& loader) { return loader.uid == uid; })) {
251                     imageLoaders_.push_back(
252                         { imageLoaderInfo->uid, imageLoaderInfo->createLoader(imageLoaderInfo->token) });
253                 }
254             } else if (type == EventType::REMOVED) {
255                 imageLoaders_.erase(std::remove_if(imageLoaders_.begin(), imageLoaders_.end(),
256                                                    [&uid = imageLoaderInfo->uid](const RegisteredImageLoader &loader) {
257                                                        return loader.uid == uid;
258                                                    }),
259                                     imageLoaders_.cend());
260             }
261         }
262     }
263 }
264 
265 CORE_END_NAMESPACE()
266