1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "MtlReader.h"
18
19 #include <android-base/logging.h>
20 #include <cstdio>
21
22 namespace android {
23 namespace hardware {
24 namespace automotive {
25 namespace sv {
26 namespace V1_0 {
27 namespace implementation {
28
29 namespace {
30
31 constexpr int kCharBufferSize = 128;
32
ReadFloat3(FILE * file,float * value)33 void ReadFloat3(FILE* file, float* value) {
34 float temp[3];
35 int res = fscanf(file, "%f %f %f", &temp[0], &temp[1], &temp[2]);
36 3 == res ? std::memcpy(value, temp, 3 * sizeof(float)) : nullptr;
37 }
38
ReadFloat(FILE * file,float * value)39 void ReadFloat(FILE* file, float* value) {
40 float temp;
41 int res = fscanf(file, "%f", &temp);
42 *value = res > 0 ? temp : -1;
43 }
44
ReadInt(FILE * file,int * value)45 void ReadInt(FILE* file, int* value) {
46 int temp;
47 int res = fscanf(file, "%d", &temp);
48 *value = res > 0 ? temp : -1;
49 }
50
ReadString(FILE * file,std::string * value)51 void ReadString(FILE* file, std::string* value) {
52 char temp[kCharBufferSize];
53 fscanf(file, "%s", temp);
54 *value = temp;
55 }
56 } // namespace
57
ReadMtlFromFile(const std::string & mtlFilename,std::map<std::string,MtlConfigParams> * params)58 bool ReadMtlFromFile(const std::string& mtlFilename,
59 std::map<std::string, MtlConfigParams>* params) {
60 FILE* file = fopen(mtlFilename.c_str(), "r");
61 if (!file) {
62 LOG(ERROR) << "Failed to open mtl file: " << mtlFilename;
63 return false;
64 }
65
66 std::string currentConfig;
67 while (true) {
68 char lineHeader[kCharBufferSize];
69 // read the first word of the line
70 int res = fscanf(file, "%s", lineHeader);
71
72 if (res == EOF) {
73 break; // EOF = End Of File. Quit the loop.
74 }
75
76 if (strcmp(lineHeader, "#") == 0) {
77 fgets(lineHeader, sizeof(lineHeader), file);
78 continue;
79 }
80 if (strcmp(lineHeader, "newmtl") == 0) {
81 res = fscanf(file, "%s", lineHeader);
82 if (params->find(lineHeader) != params->end()) {
83 fclose(file);
84 LOG(ERROR) << "Duplicated params of : " << lineHeader[0];
85 return false;
86 }
87 currentConfig = lineHeader;
88 continue;
89 }
90
91 if (strcmp(lineHeader, "Ns") == 0) {
92 ReadFloat(file, &((*params)[currentConfig].ns));
93 continue;
94 }
95 if (strcmp(lineHeader, "Ni") == 0) {
96 ReadFloat(file, &((*params)[currentConfig].ni));
97 continue;
98 }
99 if (strcmp(lineHeader, "d") == 0) {
100 ReadFloat(file, &((*params)[currentConfig].d));
101 continue;
102 }
103 if (strcmp(lineHeader, "Tr") == 0) {
104 ReadFloat(file, &((*params)[currentConfig].tr));
105 continue;
106 }
107 if (strcmp(lineHeader, "Tf") == 0) {
108 ReadFloat3(file, (*params)[currentConfig].tf);
109 continue;
110 }
111 if (strcmp(lineHeader, "illum") == 0) {
112 ReadInt(file, &((*params)[currentConfig].illum));
113 continue;
114 }
115 if (strcmp(lineHeader, "Ka") == 0) {
116 ReadFloat3(file, (*params)[currentConfig].ka);
117 continue;
118 }
119 if (strcmp(lineHeader, "Kd") == 0) {
120 ReadFloat3(file, (*params)[currentConfig].kd);
121 continue;
122 }
123 if (strcmp(lineHeader, "Ks") == 0) {
124 ReadFloat3(file, (*params)[currentConfig].ks);
125 continue;
126 }
127 if (strcmp(lineHeader, "Ke") == 0) {
128 ReadFloat3(file, (*params)[currentConfig].ke);
129 continue;
130 }
131 if (strcmp(lineHeader, "map_bump") == 0) {
132 ReadString(file, &((*params)[currentConfig].mapBump));
133 continue;
134 }
135 if (strcmp(lineHeader, "bump") == 0) {
136 ReadString(file, &((*params)[currentConfig].bump));
137 continue;
138 }
139 if (strcmp(lineHeader, "map_Ka") == 0) {
140 ReadString(file, &((*params)[currentConfig].mapKa));
141 continue;
142 }
143 if (strcmp(lineHeader, "map_Kd") == 0) {
144 ReadString(file, &((*params)[currentConfig].mapKd));
145 continue;
146 }
147 if (strcmp(lineHeader, "map_Ks") == 0) {
148 ReadString(file, &((*params)[currentConfig].mapKs));
149 continue;
150 } else {
151 LOG(WARNING) << "Unknown tag " << lineHeader << ". Skipped";
152 fgets(lineHeader, sizeof(lineHeader), file);
153 continue;
154 }
155 }
156
157 fclose(file);
158 return true;
159 }
160
161 } // namespace implementation
162 } // namespace V1_0
163 } // namespace sv
164 } // namespace automotive
165 } // namespace hardware
166 } // namespace android
167