00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "txaFile.h"
00020 #include "pal_string_utils.h"
00021 #include "palettizer.h"
00022 #include "paletteGroup.h"
00023 #include "textureImage.h"
00024
00025 #include <notify.h>
00026 #include <pnmFileTypeRegistry.h>
00027
00028
00029
00030
00031
00032
00033 TxaFile::
00034 TxaFile() {
00035 }
00036
00037
00038
00039
00040
00041
00042
00043 bool TxaFile::
00044 read(Filename filename) {
00045 filename.set_text();
00046 ifstream in;
00047 if (!filename.open_read(in)) {
00048 nout << "Unable to open " << filename << "\n";
00049 return false;
00050 }
00051
00052 string line;
00053 getline(in, line);
00054 int line_number = 1;
00055
00056 while (!in.eof() && !in.fail()) {
00057 bool okflag = true;
00058
00059
00060 size_t hash = line.find('#');
00061 if (hash != string::npos) {
00062 line = line.substr(0, hash);
00063 }
00064 line = trim_left(line);
00065 if (line.empty()) {
00066
00067
00068 } else if (line[0] == ':') {
00069
00070 vector_string words;
00071 extract_words(line, words);
00072 if (words[0] == ":group") {
00073 okflag = parse_group_line(words);
00074
00075 } else if (words[0] == ":palette") {
00076 okflag = parse_palette_line(words);
00077
00078 } else if (words[0] == ":margin") {
00079 okflag = parse_margin_line(words);
00080
00081 } else if (words[0] == ":coverage") {
00082 okflag = parse_coverage_line(words);
00083
00084 } else if (words[0] == ":imagetype") {
00085 okflag = parse_imagetype_line(words);
00086
00087 } else if (words[0] == ":shadowtype") {
00088 okflag = parse_shadowtype_line(words);
00089
00090 } else if (words[0] == ":round") {
00091 okflag = parse_round_line(words);
00092
00093 } else if (words[0] == ":remap") {
00094 okflag = parse_remap_line(words);
00095
00096 } else {
00097 nout << "Invalid keyword " << words[0] << "\n";
00098 okflag = false;
00099 }
00100
00101 } else {
00102 _lines.push_back(TxaLine());
00103 TxaLine &txa_line = _lines.back();
00104
00105 okflag = txa_line.parse(line);
00106 }
00107
00108 if (!okflag) {
00109 nout << "Error on line " << line_number << " of " << filename << "\n";
00110 return false;
00111 }
00112
00113 getline(in, line);
00114 line_number++;
00115 }
00116
00117 if (!in.eof()) {
00118 nout << "I/O error reading " << filename << "\n";
00119 return false;
00120 }
00121
00122 return true;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 bool TxaFile::
00135 match_egg(EggFile *egg_file) const {
00136 Lines::const_iterator li;
00137 for (li = _lines.begin(); li != _lines.end(); ++li) {
00138 if ((*li).match_egg(egg_file)) {
00139 return true;
00140 }
00141 }
00142
00143 return false;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 bool TxaFile::
00156 match_texture(TextureImage *texture) const {
00157 Lines::const_iterator li;
00158 for (li = _lines.begin(); li != _lines.end(); ++li) {
00159 if ((*li).match_texture(texture)) {
00160 return true;
00161 }
00162 }
00163
00164 return false;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 void TxaFile::
00175 write(ostream &out) const {
00176 Lines::const_iterator li;
00177 for (li = _lines.begin(); li != _lines.end(); ++li) {
00178 out << (*li) << "\n";
00179 }
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 bool TxaFile::
00191 parse_group_line(const vector_string &words) {
00192 vector_string::const_iterator wi;
00193 wi = words.begin();
00194 assert (wi != words.end());
00195 ++wi;
00196
00197 const string &group_name = (*wi);
00198 PaletteGroup *group = pal->get_palette_group(group_name);
00199 ++wi;
00200
00201 enum State {
00202 S_none,
00203 S_with,
00204 S_dir,
00205 };
00206 State state = S_none;
00207
00208 while (wi != words.end()) {
00209 const string &word = (*wi);
00210 if (word == "with") {
00211 state = S_with;
00212
00213 } else if (word == "dir") {
00214 state = S_dir;
00215
00216 } else {
00217 switch (state) {
00218 case S_none:
00219 nout << "Invalid keyword: " << word << "\n";
00220 return false;
00221
00222 case S_with:
00223 group->group_with(pal->get_palette_group(word));
00224 break;
00225
00226 case S_dir:
00227 group->set_dirname(word);
00228 state = S_none;
00229 break;
00230 }
00231 }
00232
00233 ++wi;
00234 }
00235
00236 return true;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246 bool TxaFile::
00247 parse_palette_line(const vector_string &words) {
00248 if (words.size() != 3) {
00249 nout << "Exactly two parameters required for :palette, the x and y "
00250 << "size of the palette images to generate.\n";
00251 return false;
00252 }
00253
00254 if (!string_to_int(words[1], pal->_pal_x_size) ||
00255 !string_to_int(words[2], pal->_pal_y_size)) {
00256 nout << "Invalid palette size: " << words[1] << " " << words[2] << "\n";
00257 return false;
00258 }
00259
00260 if (pal->_pal_x_size <= 0 || pal->_pal_y_size <= 0) {
00261 nout << "Invalid palette size: " << pal->_pal_x_size
00262 << " " << pal->_pal_y_size << "\n";
00263 return false;
00264 }
00265
00266 return true;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 bool TxaFile::
00277 parse_margin_line(const vector_string &words) {
00278 if (words.size() != 2) {
00279 nout << "Exactly one parameter required for :margin, the "
00280 << "size of the default margin to apply.\n";
00281 return false;
00282 }
00283
00284 if (!string_to_int(words[1], pal->_margin)) {
00285 nout << "Invalid margin: " << words[1] << "\n";
00286 return false;
00287 }
00288
00289 if (pal->_margin < 0) {
00290 nout << "Invalid margin: " << pal->_margin << "\n";
00291 return false;
00292 }
00293
00294 return true;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 bool TxaFile::
00305 parse_coverage_line(const vector_string &words) {
00306 if (words.size() != 2) {
00307 nout << "Exactly one parameter required for :coverage, the "
00308 << "value for the default coverage threshold.\n";
00309 return false;
00310 }
00311
00312
00313 if (!string_to_double(words[1], pal->_coverage_threshold)) {
00314 nout << "Invalid coverage threshold: " << words[1] << "\n";
00315 return false;
00316 }
00317
00318 if (pal->_coverage_threshold <= 0.0) {
00319 nout << "Invalid coverage threshold: " << pal->_coverage_threshold << "\n";
00320 return false;
00321 }
00322
00323 return true;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333 bool TxaFile::
00334 parse_imagetype_line(const vector_string &words) {
00335 if (words.size() != 2) {
00336 nout << "Exactly one parameter required for :imagetype.\n";
00337 return false;
00338 }
00339 const string &imagetype = words[1];
00340 if (!parse_image_type_request(imagetype, pal->_color_type, pal->_alpha_type)) {
00341 nout << "\nKnown image types are:\n";
00342 PNMFileTypeRegistry::get_ptr()->write_types(nout, 2);
00343 nout << "\n";
00344 return false;
00345 }
00346
00347 return true;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 bool TxaFile::
00359 parse_shadowtype_line(const vector_string &words) {
00360 if (words.size() != 2) {
00361 nout << "Exactly one parameter required for :shadowtype.\n";
00362 return false;
00363 }
00364 const string &shadowtype = words[1];
00365 if (!parse_image_type_request(shadowtype, pal->_shadow_color_type,
00366 pal->_shadow_alpha_type)) {
00367 nout << "\nKnown image types are:\n";
00368 PNMFileTypeRegistry::get_ptr()->write_types(nout, 2);
00369 nout << "\n";
00370 return false;
00371 }
00372
00373 return true;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383 bool TxaFile::
00384 parse_round_line(const vector_string &words) {
00385 if (words.size() == 2) {
00386 if (words[1] == "no") {
00387 pal->_round_uvs = false;
00388 return true;
00389 } else {
00390 nout << "Invalid round keyword: " << words[1] << ".\n"
00391 << "Expected 'no', or a round fraction and fuzz factor.\n";
00392 return false;
00393 }
00394 }
00395
00396 if (words.size() != 3) {
00397 nout << "Exactly two parameters required for :round, the fraction "
00398 << "to round to, and the fuzz factor.\n";
00399 return false;
00400 }
00401
00402 if (!string_to_double(words[1], pal->_round_unit) ||
00403 !string_to_double(words[2], pal->_round_fuzz)) {
00404 nout << "Invalid rounding: " << words[1] << " " << words[2] << "\n";
00405 return false;
00406 }
00407
00408 if (pal->_round_unit <= 0.0 || pal->_round_fuzz < 0.0) {
00409 nout << "Invalid rounding: " << pal->_round_unit
00410 << " " << pal->_round_fuzz << "\n";
00411 return false;
00412 }
00413
00414 pal->_round_uvs = true;
00415 return true;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425 bool TxaFile::
00426 parse_remap_line(const vector_string &words) {
00427 int i = 1;
00428 while (i < (int)words.size()) {
00429 const string &keyword = words[i];
00430 if (keyword == "char") {
00431
00432 i++;
00433 if (i == (int)words.size()) {
00434 nout << "Keyword expected following 'char'\n";
00435 return false;
00436 }
00437 pal->_remap_char_uv = Palettizer::string_remap(words[i]);
00438 if (pal->_remap_char_uv == Palettizer::RU_invalid) {
00439 nout << "Invalid remap keyword: " << words[i] << "\n";
00440 return false;
00441 }
00442
00443 } else {
00444
00445 pal->_remap_uv = Palettizer::string_remap(words[i]);
00446 if (pal->_remap_uv == Palettizer::RU_invalid) {
00447 nout << "Invalid remap keyword: " << words[i] << "\n";
00448 return false;
00449 }
00450
00451 pal->_remap_char_uv = pal->_remap_uv;
00452 }
00453
00454 i++;
00455 }
00456
00457 return true;
00458 }