• 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 #ifndef CORE_IMAGE_LOADERS_IMAGE_LOADER_COMMON_H
17 #define CORE_IMAGE_LOADERS_IMAGE_LOADER_COMMON_H
18 
19 #include <functional>
20 #include <limits>
21 #include <base/math/mathf.h>
22 #include <core/io/intf_file_manager.h>
23 #include <core/log.h>
24 #include <core/namespace.h>
25 
26 #include "image/image_loader_manager.h"
27 
CORE_BEGIN_NAMESPACE()28 CORE_BEGIN_NAMESPACE()
29 
30 class ImageLoaderCommon {
31 public:
32     static ImageLoaderCommon &GetInstance();
33 
34     bool PremultiplyAlpha(uint8_t *imageBytes, uint32_t width, uint32_t height, uint32_t channelCount,
35         uint32_t bytesPerChannel, bool linear);
36 
37 private:
38     ImageLoaderCommon() = default;
39     ~ImageLoaderCommon() = default;
40 
41     ImageLoaderCommon(const ImageLoaderCommon &imgLoaderCommon) = delete;
42     const ImageLoaderCommon &operator=(const ImageLoaderCommon &imgLoaderCommon) = delete;
43 
44     void InitializeSRGBTable();
45 
46     uint8_t SRGBPremultiplyLookup[256u * 256u] = {0};
47 };
48 
49 void FreeLibBaseImageBytes(void *imageBytes);
50 
51 using LibBaseImageDeleter = std::function<void(void *)>;
52 using LibBaseImagePtr = BASE_NS::unique_ptr<void, LibBaseImageDeleter>;
53 
54 class LibBaseImage : public IImageContainer {
55 public:
56     LibBaseImage();
57 
58     virtual ~LibBaseImage() = default;
59 
60     using Ptr = BASE_NS::unique_ptr<LibBaseImage, Deleter>;
61 
62     const ImageDesc &GetImageDesc() const override;
63 
64     BASE_NS::array_view<const uint8_t> GetData() const override;
65 
66     BASE_NS::array_view<const SubImageDesc> GetBufferImageCopies() const override;
67 
68     static constexpr BASE_NS::Format ResolveFormat(uint32_t loadFlags, uint32_t componentCount, bool is16bpc);
69 
70     constexpr static ImageDesc ResolveImageDesc(BASE_NS::Format format, uint32_t imageWidth, uint32_t imageHeight,
71         uint32_t bitsPerPixel, bool generateMips, bool isPremultiplied);
72 
73     static ImageLoaderManager::LoadResult CreateImage(LibBaseImagePtr imageBytes, uint32_t imageWidth,
74         uint32_t imageHeight, uint32_t componentCount, uint32_t loadFlags, bool is16bpc);
75 
76     struct Info {
77         uint32_t width;
78         uint32_t height;
79         uint32_t componentCount;
80         bool is16bpc;
81     };
82 
83 protected:
84     virtual void Destroy() override;
85     ImageDesc imageDesc_;
86     SubImageDesc imageBuffer_;
87 
88     LibBaseImagePtr imageBytes_;
89     size_t imageBytesLength_ = 0;
90 };
91 
92 template <typename T>
93 class RowPointers {
94 public:
95     T **rowPointers = nullptr;
96     int allocHeight = 0;
97     bool allocSucc = false;
98 
RowPointers(uint32_t width,uint32_t height,uint32_t channels,uint32_t channelSize)99     RowPointers(uint32_t width, uint32_t height, uint32_t channels, uint32_t channelSize)
100     {
101         if (height <= 0 || height > static_cast<size_t>(std::numeric_limits<int>::max())) {
102             allocSucc = false;
103             return;
104         }
105         rowPointers = (T **)malloc(height * sizeof(T *));
106         allocHeight = static_cast<int>(height);
107 
108         size_t rowbytes = width * channels * channelSize;
109         if (rowbytes <= 0 || rowbytes > static_cast<size_t>(std::numeric_limits<int>::max())) {
110             allocSucc = false;
111             return;
112         }
113         for (int i = 0; i < allocHeight; i++) {
114             rowPointers[i] = nullptr; /* security precaution */
115         }
116         for (int i = 0; i < allocHeight; i++) {
117             rowPointers[i] = (T *)malloc(rowbytes);
118         }
119         allocSucc = true;
120     }
121 
~RowPointers()122     ~RowPointers()
123     {
124         if (rowPointers) {
125             for (int i = 0; i < allocHeight; i++) {
126                 if (rowPointers[i]) {
127                     free(rowPointers[i]);
128                 }
129             }
130             free(rowPointers);
131         }
132     }
133 };
134 
135 template <typename T>
136 class ArrayLoader {
137 public:
ArrayLoader(BASE_NS::array_view<const T> imageFileBytes)138     ArrayLoader(BASE_NS::array_view<const T> imageFileBytes)
139     {
140         buf = imageFileBytes;
141         arrSize = imageFileBytes.size();
142         curr = 0;
143     }
ArrayRead(T * dest,uint64_t length)144     void ArrayRead(T *dest, uint64_t length)
145     {
146         if (curr + length > arrSize) {
147             CORE_LOG_E("ArrayLoader out of range.");
148             return;
149         }
150         int ret = memcpy_s(dest, length, static_cast<const T *>(buf.data()) + curr, length);
151         if (ret != 0) {
152             CORE_LOG_E("memcpy_s in ArrayLoader error.");
153             return;
154         }
155         curr += length;
156     }
157 
158 private:
159     BASE_NS::array_view<const T> buf;
160     uint64_t curr;
161     uint64_t arrSize;
162 };
163 
164 template <typename T>
VerticalFlipRowPointers(T ** rowPointers,uint32_t height,uint32_t width,uint32_t channels)165 void VerticalFlipRowPointers(T **rowPointers, uint32_t height, uint32_t width, uint32_t channels)
166 {
167     uint32_t halfWidth = width / 2;
168     for (uint32_t y = 0; y < height; y++) {
169         for (uint32_t x = 0; x < halfWidth; x++) {
170             for (uint32_t k = 0; k < channels; k++) {
171                 uint32_t idx = x * channels + k;
172                 uint32_t ridx = (width - x - 1) * channels + k;
173                 T tempPixel = rowPointers[y][idx];
174                 rowPointers[y][idx] = rowPointers[y][ridx];
175                 rowPointers[y][ridx] = tempPixel;
176             }
177         }
178     }
179 }
180 
181 template <typename T>
VerticalFlipRow(T * rowPointer,uint32_t width,uint32_t channels)182 void VerticalFlipRow(T *rowPointer, uint32_t width, uint32_t channels)
183 {
184     uint32_t halfWidth = width / 2;
185     for (uint32_t x = 0; x < halfWidth; x++) {
186         for (uint32_t k = 0; k < channels; k++) {
187             uint32_t idx = x * channels + k;
188             uint32_t ridx = (width - x - 1) * channels + k;
189             T tempPixel = rowPointer[idx];
190             rowPointer[idx] = rowPointer[ridx];
191             rowPointer[ridx] = tempPixel;
192         }
193     }
194 }
195 
196 CORE_END_NAMESPACE()
197 
198 #endif  //  CORE_IMAGE_LOADERS_IMAGE_LOADER_COMMON_H