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 "filter_factory.h"
17 #include "ec_log.h"
18 #include "builder.h"
19
20 namespace OHOS {
21 namespace Rosen {
CreateFromConfig(std::string path)22 ImageChain* Builder::CreateFromConfig(std::string path)
23 {
24 char newpath[PATH_MAX + 1] = { 0x00 };
25 if (strlen(path.c_str()) > PATH_MAX || realpath(path.c_str(), newpath) == NULL) {
26 return nullptr;
27 }
28
29 std::ifstream configFile;
30 configFile.open(newpath);
31 std::stringstream JFilterParamsStream;
32 JFilterParamsStream << configFile.rdbuf();
33 configFile.close();
34 std::string JFilterParamsString = JFilterParamsStream.str();
35 auto overallData = std::shared_ptr<cJSON>(cJSON_Parse(JFilterParamsString.c_str()));
36 if (overallData != nullptr) {
37 filters_ = std::shared_ptr<cJSON>(cJSON_GetObjectItem(overallData.get(), "filters"));
38 if (filters_ != nullptr) {
39 AnalyseFilters(filters_.get());
40 }
41 connections_ = std::shared_ptr<cJSON>(cJSON_GetObjectItem(overallData.get(), "connections"));
42 if (connections_ != nullptr) {
43 ConnectPipeline(connections_.get());
44 }
45 } else {
46 LOGE("The json file fails to compile.");
47 return nullptr;
48 }
49 if (inputs_.size() != 0) {
50 return new ImageChain(inputs_);
51 } else {
52 LOGE("No input.");
53 return nullptr;
54 }
55 }
56
AnalyseFilters(cJSON * filters)57 void Builder::AnalyseFilters(cJSON* filters)
58 {
59 int size = cJSON_GetArraySize(filters);
60 for (int i = 0; i < size; i++) {
61 auto item = std::shared_ptr<cJSON>(cJSON_GetArrayItem(filters, i));
62 auto type = std::shared_ptr<cJSON>(cJSON_GetObjectItem(item.get(), "type"));
63 auto name = std::shared_ptr<cJSON>(cJSON_GetObjectItem(item.get(), "name"));
64 auto params = std::shared_ptr<cJSON>(cJSON_GetObjectItem(item.get(), "params"));
65 if (type != nullptr && name != nullptr) {
66 nameType_[name->valuestring] = type->valuestring;
67 auto tempFilter = filterFactory->GetFilter(type->valuestring);
68 if (tempFilter != nullptr) {
69 ParseParams(tempFilter, params.get());
70 nameFilter_[name->valuestring] = tempFilter;
71 }
72 }
73 }
74 }
75
ParseParams(std::shared_ptr<Filter> filter,cJSON * params)76 void Builder::ParseParams(std::shared_ptr<Filter> filter, cJSON* params)
77 {
78 if (params == nullptr) {
79 return;
80 }
81 auto childParam = std::shared_ptr<cJSON>(params->child);
82 while (childParam != nullptr) {
83 if (cJSON_IsArray(childParam.get())) {
84 ParseArray(filter, childParam.get());
85 } else if (cJSON_IsNumber(childParam.get())) {
86 std::shared_ptr<float> tempValue = std::make_shared<float>(childParam->valuedouble);
87 filter->SetValue(childParam->string, tempValue, 1);
88 } else if (cJSON_IsString(childParam.get())) {
89 std::string tempString = childParam->valuestring;
90 std::shared_ptr<std::string> tempValue = std::make_shared<std::string>(tempString);
91 filter->SetValue(childParam->string, tempValue, 1);
92 } else {
93 LOGE("Invalid input parameters!");
94 }
95 childParam = std::shared_ptr<cJSON>(childParam->next);
96 }
97 }
98
ParseArray(std::shared_ptr<Filter> filter,cJSON * childParam)99 void Builder::ParseArray(std::shared_ptr<Filter> filter, cJSON* childParam)
100 {
101 if (filter == nullptr || childParam == nullptr) {
102 return;
103 }
104 int arrayLength = cJSON_GetArraySize(childParam);
105 std::shared_ptr<std::vector<float>> tempArray = std::make_shared<std::vector<float>>(arrayLength, 0);
106 for (int i = 0; i < arrayLength; i++) {
107 auto arrayItem = std::shared_ptr<cJSON>(cJSON_GetArrayItem(childParam, i));
108 if (cJSON_IsNumber(arrayItem.get())) {
109 (*tempArray.get())[i] = arrayItem->valuedouble;
110 }
111 }
112 filter->SetValue(childParam->string, tempArray, arrayLength);
113 }
114
ConnectPipeline(cJSON * connections)115 void Builder::ConnectPipeline(cJSON* connections)
116 {
117 int size = cJSON_GetArraySize(connections);
118 for (int i = 0; i < size; i++) {
119 auto item = std::shared_ptr<cJSON>(cJSON_GetArrayItem(connections, i));
120 auto from = std::shared_ptr<cJSON>(cJSON_GetObjectItem(item.get(), "from"));
121 auto to = std::shared_ptr<cJSON>(cJSON_GetObjectItem(item.get(), "to"));
122 std::shared_ptr<Filter> fFilter = nullptr;
123 std::shared_ptr<Filter> tFilter = nullptr;
124 if (from != nullptr && to != nullptr) {
125 auto itFrom = nameFilter_.find(from->valuestring);
126 if (itFrom != nameFilter_.end()) {
127 fFilter = itFrom->second;
128 if (fFilter->GetFilterType() == FILTER_TYPE::INPUT) {
129 inputs_.push_back(std::static_pointer_cast<Input>(fFilter));
130 }
131 } else {
132 LOGE("The from filter %{public}s fails to be connected", from->valuestring);
133 }
134 auto itTo = nameFilter_.find(to->valuestring);
135 if (itTo != nameFilter_.end()) {
136 tFilter = itTo->second;
137 } else {
138 LOGE("The to filter %{public}s fails to be connected", to->valuestring);
139 }
140 if (fFilter != nullptr && tFilter != nullptr) {
141 fFilter->AddNextFilter(tFilter);
142 }
143 }
144 }
145 }
146 } // namespcae Rosen
147 } // namespace OHOS
148