1 /*
2 * Copyright (c) 2025 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 #define LOG_TAG "PixelmapLoader"
16
17 #include "pixelmap_loader.h"
18
19 #include <dlfcn.h>
20 #include <thread>
21 #include "logger.h"
22 #include "pixel_map.h"
23
24 namespace OHOS {
25 namespace UDMF {
26
27 static constexpr const char* PIXEL_MAP_WRAPPER_SO_NAME = "libpixelmap_wrapper.z.so";
28 static constexpr const char* DECODE_TLV = "DecodeTlv";
29 static constexpr const char* ENCODE_TLV = "EncodeTlv";
30 static constexpr const char* GET_PIXEL_MAP_FROM_RAW_DATA = "GetPixelMapFromRawData";
31 static constexpr const char* PARSE_INFO_FROM_PIXEL_MAP = "ParseInfoFromPixelMap";
32
33 std::weak_ptr<void> PixelMapLoader::SoAutoUnloadManager::weakHandler_;
34 std::mutex PixelMapLoader::SoAutoUnloadManager::mutex_;
35
GetHandler()36 std::shared_ptr<void> PixelMapLoader::SoAutoUnloadManager::GetHandler()
37 {
38 {
39 std::lock_guard<std::mutex> lock(mutex_);
40 if (auto real = weakHandler_.lock()) {
41 return real;
42 }
43 }
44 LOG_INFO(UDMF_KITS_INNER, "dlopen start");
45 void *rawHandler = dlopen(PIXEL_MAP_WRAPPER_SO_NAME, RTLD_NOW);
46 if (rawHandler == nullptr) {
47 LOG_ERROR(UDMF_KITS_INNER, "dlopen error! msg=%{public}s", dlerror());
48 return nullptr;
49 }
50
51 auto deleter = [](void *h) {
52 if (h) dlclose(h);
53 };
54 std::shared_ptr<void> sp(rawHandler, deleter);
55
56 {
57 std::lock_guard<std::mutex> lock(mutex_);
58 if (auto existed = weakHandler_.lock()) {
59 return existed;
60 }
61 weakHandler_ = sp;
62 return sp;
63 }
64 }
65
PixelMapLoader()66 PixelMapLoader::PixelMapLoader()
67 {
68 handler_ = SoAutoUnloadManager::GetHandler();
69 if (handler_ == nullptr) {
70 LOG_ERROR(UDMF_KITS_INNER, "handler is null!");
71 }
72 }
73
DecodeTlv(std::vector<uint8_t> & buff)74 std::shared_ptr<OHOS::Media::PixelMap> PixelMapLoader::DecodeTlv(std::vector<uint8_t> &buff)
75 {
76 if (buff.empty()) {
77 LOG_ERROR(UDMF_KITS_INNER, "buff is empty!");
78 return nullptr;
79 }
80 if (handler_ == nullptr) {
81 LOG_ERROR(UDMF_KITS_INNER, "handler is null!");
82 return nullptr;
83 }
84 PixelMapDetails details;
85 details.rawData = std::ref(buff);
86 auto loadDecodeTlv = reinterpret_cast<LoadDecodeTlv>(dlsym(handler_.get(), DECODE_TLV));
87 if (loadDecodeTlv == nullptr) {
88 LOG_ERROR(UDMF_KITS_INNER, "dlsym error! msg=%{public}s", dlerror());
89 return nullptr;
90 }
91
92 OHOS::Media::PixelMap *raw = loadDecodeTlv(details);
93 if (raw == nullptr) {
94 LOG_ERROR(UDMF_KITS_INNER, "pixelMap is null!");
95 return nullptr;
96 }
97 auto deleter = [handler = handler_](OHOS::Media::PixelMap *p) {
98 delete p;
99 };
100 return std::shared_ptr<OHOS::Media::PixelMap>(raw, deleter);
101 }
102
EncodeTlv(const std::shared_ptr<OHOS::Media::PixelMap> pixelMap,std::vector<uint8_t> & buff)103 bool PixelMapLoader::EncodeTlv(const std::shared_ptr<OHOS::Media::PixelMap> pixelMap, std::vector<uint8_t> &buff)
104 {
105 if (pixelMap == nullptr) {
106 LOG_ERROR(UDMF_KITS_INNER, "pixelMap is nullptr!");
107 return false;
108 }
109 if (handler_ == nullptr) {
110 LOG_ERROR(UDMF_KITS_INNER, "handler is null!");
111 return false;
112 }
113 auto loadEncodeTlv = reinterpret_cast<LoadEncodeTlv>(dlsym(handler_.get(), ENCODE_TLV));
114 if (loadEncodeTlv == nullptr) {
115 LOG_ERROR(UDMF_KITS_INNER, "dlsym error! msg=%{public}s", dlerror());
116 return false;
117 }
118 auto details = std::make_shared<PixelMapDetails>();
119 details->rawDataResult.emplace();
120 auto result = loadEncodeTlv(pixelMap.get(), details.get());
121 if (details->rawDataResult->empty()) {
122 LOG_ERROR(UDMF_KITS_INNER, "encodeTlv fail");
123 return result;
124 }
125 buff = std::move(*details->rawDataResult);
126 return result;
127 }
128
GetPixelMapFromRawData(const PixelMapDetails & details)129 std::shared_ptr<OHOS::Media::PixelMap> PixelMapLoader::GetPixelMapFromRawData(const PixelMapDetails &details)
130 {
131 if (!details.rawData.has_value()) {
132 LOG_ERROR(UDMF_KITS_INNER, "buff is empty!");
133 return nullptr;
134 }
135 if (handler_ == nullptr) {
136 LOG_ERROR(UDMF_KITS_INNER, "handler is null!");
137 return nullptr;
138 }
139 auto loadGetPixelMapFromRawData = reinterpret_cast<LoadGetPixelMapFromRawData>(
140 dlsym(handler_.get(), GET_PIXEL_MAP_FROM_RAW_DATA));
141 if (loadGetPixelMapFromRawData == nullptr) {
142 LOG_ERROR(UDMF_KITS_INNER, "dlsym error! msg=%{public}s", dlerror());
143 return nullptr;
144 }
145 OHOS::Media::PixelMap *raw = loadGetPixelMapFromRawData(details);
146 if (raw == nullptr) {
147 LOG_ERROR(UDMF_KITS_INNER, "pixelMap is null!");
148 return nullptr;
149 }
150 auto deleter = [handler = handler_](OHOS::Media::PixelMap *p) {
151 delete p;
152 };
153 return std::shared_ptr<OHOS::Media::PixelMap>(raw, deleter);
154 }
155
ParseInfoFromPixelMap(const std::shared_ptr<OHOS::Media::PixelMap> pixelMap)156 std::shared_ptr<PixelMapDetails> PixelMapLoader::ParseInfoFromPixelMap(
157 const std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
158 {
159 if (pixelMap == nullptr) {
160 LOG_ERROR(UDMF_KITS_INNER, "pixelMap is nullptr!");
161 return nullptr;
162 }
163 if (handler_ == nullptr) {
164 LOG_ERROR(UDMF_KITS_INNER, "handler is null!");
165 return nullptr;
166 }
167 auto loadParseInfoFromPixelMap = reinterpret_cast<LoadParseInfoFromPixelMap>(
168 dlsym(handler_.get(), PARSE_INFO_FROM_PIXEL_MAP));
169 if (loadParseInfoFromPixelMap == nullptr) {
170 LOG_ERROR(UDMF_KITS_INNER, "dlsym error! msg=%{public}s", dlerror());
171 return nullptr;
172 }
173 return std::shared_ptr<PixelMapDetails>(loadParseInfoFromPixelMap(pixelMap.get()));
174 }
175
176 } // namespace UDMF
177 } // namespace OHOS