• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 #include <cctype>
20 #include <cstring>
21 
22 #include <core/io/intf_file.h>
23 #include <core/log.h>
24 #include <core/namespace.h>
25 #include <core/perf/cpu_perf_scope.h>
26 #include <core/perf/intf_performance_data_manager.h>
27 
28 CORE_BEGIN_NAMESPACE()
29 using BASE_NS::array_view;
30 using BASE_NS::make_unique;
31 using BASE_NS::move;
32 using BASE_NS::string_view;
33 using BASE_NS::unique_ptr;
34 
RegisterImageLoader(IImageLoader::Ptr imageLoader)35 void ImageLoaderManager::RegisterImageLoader(IImageLoader::Ptr imageLoader)
36 {
37     if (!imageLoader) {
38         CORE_LOG_D("imageLoader is null, Not adding.");
39         return;
40     }
41 
42     // NOTE: We just add the registered unique pointers to a vector. The vector is not really used for anything else.
43     // And the loaders cannot be currently unregistered.
44     imageLoaders_.push_back(std::move(imageLoader));
45 }
46 
LoadImage(const string_view uri,uint32_t loadFlags)47 ImageLoaderManager::LoadResult ImageLoaderManager::LoadImage(const string_view uri, uint32_t loadFlags)
48 {
49     CORE_CPU_PERF_SCOPE("Image", "loadImage()", uri);
50 
51     // Load 12 bytes (maximum header size of currently implemented file types)
52     IFile::Ptr file = fileManager_.OpenFile(uri);
53     if (!file) {
54         return ResultFailure("Can not open image.");
55     }
56 
57     return LoadImage(*file, loadFlags);
58 }
59 
LoadImage(IFile & file,uint32_t loadFlags)60 ImageLoaderManager::LoadResult ImageLoaderManager::LoadImage(IFile& file, uint32_t loadFlags)
61 {
62     CORE_CPU_PERF_SCOPE("Image", "loadImage()", "file");
63 
64     const uint64_t byteLength = 12u;
65 
66     // Read header of the file to a buffer.
67     unique_ptr<uint8_t[]> buffer = make_unique<uint8_t[]>(static_cast<size_t>(byteLength));
68     const uint64_t read = file.Read(buffer.get(), byteLength);
69     if (read != byteLength) {
70         return ResultFailure("Can not read file header.");
71     }
72     file.Seek(0);
73 
74     for (auto& loader : imageLoaders_) {
75         if (loader->CanLoad(array_view<const uint8_t>(buffer.get(), static_cast<size_t>(byteLength)))) {
76             return loader->Load(file, loadFlags);
77         }
78     }
79     return ResultFailure("Image loader not found for this format.");
80 }
81 
LoadImage(array_view<const uint8_t> imageFileBytes,uint32_t loadFlags)82 ImageLoaderManager::LoadResult ImageLoaderManager::LoadImage(
83     array_view<const uint8_t> imageFileBytes, uint32_t loadFlags)
84 {
85     CORE_CPU_PERF_SCOPE("Image", "loadImage(bytes)", "memory");
86 
87     for (auto& loader : imageLoaders_) {
88         if (loader->CanLoad(imageFileBytes)) {
89             return loader->Load(imageFileBytes, loadFlags);
90         }
91     }
92 
93     return ResultFailure("Image loader not found for this format.");
94 }
95 
LoadAnimatedImage(const string_view uri,uint32_t loadFlags)96 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::LoadAnimatedImage(const string_view uri, uint32_t loadFlags)
97 {
98     CORE_CPU_PERF_SCOPE("Image", "loadAnimatedImage()", uri);
99 
100     // Load 12 bytes (maximum header size of currently implemented file types)
101     IFile::Ptr file = fileManager_.OpenFile(uri);
102     if (!file) {
103         return ResultFailureAnimated("Can not open image.");
104     }
105 
106     return LoadAnimatedImage(*file, loadFlags);
107 }
108 
LoadAnimatedImage(IFile & file,uint32_t loadFlags)109 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::LoadAnimatedImage(IFile& file, uint32_t loadFlags)
110 {
111     CORE_CPU_PERF_SCOPE("Image", "loadAnimatedImage()", "file");
112 
113     const uint64_t byteLength = 12u;
114 
115     // Read header of the file to a buffer.
116     unique_ptr<uint8_t[]> buffer = make_unique<uint8_t[]>(static_cast<size_t>(byteLength));
117     const uint64_t read = file.Read(buffer.get(), byteLength);
118     if (read != byteLength) {
119         return ResultFailureAnimated("Can not read file header.");
120     }
121     file.Seek(0);
122 
123     for (auto& loader : imageLoaders_) {
124         if (loader->CanLoad(array_view<const uint8_t>(buffer.get(), static_cast<size_t>(byteLength)))) {
125             return loader->LoadAnimatedImage(file, loadFlags);
126         }
127     }
128     return ResultFailureAnimated("Image loader not found for this format.");
129 }
130 
LoadAnimatedImage(array_view<const uint8_t> imageFileBytes,uint32_t loadFlags)131 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::LoadAnimatedImage(
132     array_view<const uint8_t> imageFileBytes, uint32_t loadFlags)
133 {
134     CORE_CPU_PERF_SCOPE("Image", "loadAnimatedImage(bytes)", "memory");
135 
136     for (auto& loader : imageLoaders_) {
137         if (loader->CanLoad(imageFileBytes)) {
138             return loader->LoadAnimatedImage(imageFileBytes, loadFlags);
139         }
140     }
141 
142     return ResultFailureAnimated("Image loader not found for this format.");
143 }
144 
ResultFailure(const string_view error)145 ImageLoaderManager::LoadResult ImageLoaderManager::ResultFailure(const string_view error)
146 {
147     LoadResult result {
148         false,  // if success
149         "",     // array error[128];
150         nullptr // the image;
151     };
152 
153     // Copy the error string
154     const auto count = std::min(error.size(), sizeof(result.error) - 1);
155     error.copy(result.error, count);
156     result.error[count] = '\0';
157 
158     return result;
159 }
160 
ResultSuccess(IImageContainer::Ptr image)161 ImageLoaderManager::LoadResult ImageLoaderManager::ResultSuccess(IImageContainer::Ptr image)
162 {
163     return LoadResult {
164         true,       // if success
165         "",         // array error[128];
166         move(image) // the image;
167     };
168 }
169 
ResultFailureAnimated(const string_view error)170 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::ResultFailureAnimated(const string_view error)
171 {
172     LoadAnimatedResult result {
173         false,  // if success
174         "",     // array error[128];
175         nullptr // the image;
176     };
177 
178     // Copy the error string
179     const auto count = std::min(error.size(), sizeof(result.error) - 1);
180     error.copy(result.error, count);
181     result.error[count] = '\0';
182 
183     return result;
184 }
185 
ResultSuccessAnimated(IAnimatedImage::Ptr image)186 ImageLoaderManager::LoadAnimatedResult ImageLoaderManager::ResultSuccessAnimated(IAnimatedImage::Ptr image)
187 {
188     return LoadAnimatedResult {
189         true,       // if success
190         "",         // array error[128];
191         move(image) // the image;
192     };
193 }
194 CORE_END_NAMESPACE()
195