From e3abfcffc3d81a4de6cc770abb23dbb70aaffaf5 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 12 Sep 2003 05:11:05 +0000 Subject: [PATCH] add -as, -nodb, -tn --- pandatool/src/egg-palettize/eggPalettize.cxx | 173 ++++++++++++------ pandatool/src/egg-palettize/eggPalettize.h | 5 + pandatool/src/egg-palettize/paletteImage.cxx | 46 ++++- pandatool/src/egg-palettize/palettizer.cxx | 33 ++-- pandatool/src/egg-palettize/palettizer.h | 3 +- .../src/egg-palettize/sourceTextureImage.cxx | 10 +- .../src/egg-palettize/sourceTextureImage.h | 2 +- pandatool/src/egg-palettize/txaFile.cxx | 45 +++-- pandatool/src/egg-palettize/txaFile.h | 10 +- 9 files changed, 229 insertions(+), 98 deletions(-) diff --git a/pandatool/src/egg-palettize/eggPalettize.cxx b/pandatool/src/egg-palettize/eggPalettize.cxx index b0a0d394da..832d39cc9e 100644 --- a/pandatool/src/egg-palettize/eggPalettize.cxx +++ b/pandatool/src/egg-palettize/eggPalettize.cxx @@ -69,26 +69,58 @@ EggPalettize() : EggMultiFilter(true) { _force_complete = true; add_option - ("a", "filename", 0, + ("af", "filename", 0, "Read the indicated file as the .txa file. The default is textures.txa.", &EggPalettize::dispatch_filename, &_got_txa_filename, &_txa_filename); + add_option + ("a", "filename", 0, + "Deprecated option. This is the same as -af.", + &EggPalettize::dispatch_filename, &_got_txa_filename, &_txa_filename); + + add_option + ("as", "script", 0, + "Accept the script specified on the command line as the contents of the " + ".txa file, instead of reading a file on disk. This implies -nodb and " + "-opt.", + &EggPalettize::dispatch_string, &_got_txa_script, &_txa_script); + + add_option + ("nodb", "", 0, + "Don't read or record the state information to a .boo file. By default, " + "the palettization information is recorded so it can be preserved " + "between multiple invocations of egg-palettize. If you specify this " + "parameter, all the egg files to be palettized together must be " + "named at the same time. This also implies -opt, since there's no point " + "in not making an optimal packing if you won't be preserving the " + "state for future adjustments.", + &EggPalettize::dispatch_none, &_nodb); + + add_option + ("tn", "pattern", 0, + "Specify the name to generate for each palette image. The string should " + "contain %g for the group name, %p for the page name, and %i for the " + "index within the page. The extension is inferred from the image " + "type. The default is '%g_palette_%p_%i'.", + &EggPalettize::dispatch_string, &_got_generated_image_pattern, + &_generated_image_pattern); + add_option ("pi", "", 0, "Do not process anything, but instead report the detailed palettization " - "information.", + "information written in the state file.", &EggPalettize::dispatch_none, &_report_pi); add_option ("s", "", 0, "Do not process anything, but report statistics on palette " - "and texture utilization.", + "and texture utilization from the state file.", &EggPalettize::dispatch_none, &_report_statistics); add_option ("R", "", 0, "Remove the named egg files from the previously-generated state data " - "in textures.boo.", + "file.", &EggPalettize::dispatch_none, &_remove_eggs); // We redefine -d using add_option() instead of redescribe_option() @@ -507,31 +539,48 @@ run() { loader_cat->set_severity(NS_warning); } - if (!_txa_filename.exists() && !_got_txa_filename) { - // If we did not specify a filename, and the default filename of - // "textures.txa" doesn't exist, try looking in src/maps, as - // another likely possibility. - Filename maybe = _txa_filename; - maybe.set_dirname("src/maps"); - if (maybe.exists()) { - _txa_filename = maybe; - } - } - - if (!_txa_filename.exists()) { - nout << FilenameUnifier::make_user_filename(_txa_filename) - << " does not exist; cannot run.\n"; - exit(1); - } - - FilenameUnifier::set_txa_filename(_txa_filename); - - Filename state_filename = _txa_filename; - state_filename.set_extension("boo"); - + Filename state_filename; BamFile state_file; - if (!state_filename.exists()) { + if (_got_txa_script) { + // If we got a command-line script instead of a .txa file, we + // won't be encoding a .boo file either. + _nodb = true; + + } else { + // Look for the .txa file. + if (!_txa_filename.exists() && !_got_txa_filename) { + // If we did not specify a filename, and the default filename of + // "textures.txa" doesn't exist, try looking in src/maps, as + // another likely possibility. + Filename maybe = _txa_filename; + maybe.set_dirname("src/maps"); + if (maybe.exists()) { + _txa_filename = maybe; + } + } + + if (!_txa_filename.exists()) { + nout << FilenameUnifier::make_user_filename(_txa_filename) + << " does not exist; cannot run.\n"; + exit(1); + } + + FilenameUnifier::set_txa_filename(_txa_filename); + + state_filename = _txa_filename; + state_filename.set_extension("boo"); + } + + if (_nodb) { + // -nodb means don't attempt to read textures.boo; in fact, don't + // even bother reporting this absence to the user. + pal = new Palettizer; + + // And -nodb implies -opt. + _optimal = true; + + } else if (!state_filename.exists()) { nout << FilenameUnifier::make_user_filename(state_filename) << " does not exist; starting palettization from scratch.\n"; pal = new Palettizer; @@ -599,7 +648,23 @@ run() { bool okflag = true; - pal->read_txa_file(_txa_filename); + if (_got_txa_script) { + istringstream txa_script(_txa_script); + pal->read_txa_file(txa_script, "command line"); + + } else { + _txa_filename.set_text(); + ifstream txa_file; + if (!_txa_filename.open_read(txa_file)) { + nout << "Unable to open " << _txa_filename << "\n"; + exit(1); + } + pal->read_txa_file(txa_file, _txa_filename); + } + + if (_got_generated_image_pattern) { + pal->_generated_image_pattern = _generated_image_pattern; + } if (_got_default_groupname) { pal->_default_groupname = _default_groupname; @@ -687,31 +752,33 @@ run() { okflag = false; } - // Make up a temporary filename to write the state file to, then - // move the state file into place. We do this in case the user - // interrupts us (or we core dump) before we're done; that way we - // won't leave the state file incompletely written. - string dirname = state_filename.get_dirname(); - if (dirname.empty()) { - dirname = "."; - } - Filename temp_filename = Filename::temporary(dirname, "pi"); - - if (!state_file.open_write(temp_filename) || - !state_file.write_object(pal)) { - nout << "Unable to write palettization information to " - << FilenameUnifier::make_user_filename(temp_filename) - << "\n"; - exit(1); - } - - state_file.close(); - state_filename.unlink(); - if (!temp_filename.rename_to(state_filename)) { - nout << "Unable to rename temporary file " - << FilenameUnifier::make_user_filename(temp_filename) << " to " - << FilenameUnifier::make_user_filename(state_filename) << "\n"; - exit(1); + if (!_nodb) { + // Make up a temporary filename to write the state file to, then + // move the state file into place. We do this in case the user + // interrupts us (or we core dump) before we're done; that way we + // won't leave the state file incompletely written. + string dirname = state_filename.get_dirname(); + if (dirname.empty()) { + dirname = "."; + } + Filename temp_filename = Filename::temporary(dirname, "pi"); + + if (!state_file.open_write(temp_filename) || + !state_file.write_object(pal)) { + nout << "Unable to write palettization information to " + << FilenameUnifier::make_user_filename(temp_filename) + << "\n"; + exit(1); + } + + state_file.close(); + state_filename.unlink(); + if (!temp_filename.rename_to(state_filename)) { + nout << "Unable to rename temporary file " + << FilenameUnifier::make_user_filename(temp_filename) << " to " + << FilenameUnifier::make_user_filename(state_filename) << "\n"; + exit(1); + } } if (!okflag) { diff --git a/pandatool/src/egg-palettize/eggPalettize.h b/pandatool/src/egg-palettize/eggPalettize.h index dcf43302b1..22b0692f78 100644 --- a/pandatool/src/egg-palettize/eggPalettize.h +++ b/pandatool/src/egg-palettize/eggPalettize.h @@ -43,6 +43,11 @@ public: // and palettes. These values are copied to the Palettizer. bool _got_txa_filename; Filename _txa_filename; + bool _got_txa_script; + string _txa_script; + bool _nodb; + string _generated_image_pattern; + bool _got_generated_image_pattern; string _map_dirname; bool _got_map_dirname; Filename _shadow_dirname; diff --git a/pandatool/src/egg-palettize/paletteImage.cxx b/pandatool/src/egg-palettize/paletteImage.cxx index c3fde1525f..f102a92027 100644 --- a/pandatool/src/egg-palettize/paletteImage.cxx +++ b/pandatool/src/egg-palettize/paletteImage.cxx @@ -174,15 +174,51 @@ PaletteImage(PalettePage *page, int index) : _new_image = true; _got_image = false; - ostringstream name; + // Build up the basename for the palette image, based on the + // supplied image pattern. + string::iterator si = pal->_generated_image_pattern.begin(); + while (si != pal->_generated_image_pattern.end()) { + if ((*si) == '%') { + // Some keycode. + ++si; + if (si != pal->_generated_image_pattern.end()) { + switch (*si) { + case '%': + _basename += '%'; + break; + + case 'g': + _basename += page->get_group()->get_name(); + break; + + case 'p': + _basename += page->get_name(); + break; + + case 'i': + _basename += format_string(index + 1); + break; + + default: + _basename += '%'; + _basename += (*si); + } + ++si; + } + } else { + // A literal character. + _basename += (*si); + ++si; + } + } + // We must end the basename with a dot, so that it does not appear // to have a filename extension. Otherwise, an embedded dot in the // group's name would make everything following appear to be an // extension, which would get lost in the set_filename() call. - name << page->get_group()->get_name() << "_palette_" - << page->get_name() << "_" << index + 1 << "."; - - _basename = name.str(); + if (_basename.empty() || _basename[_basename.length() - 1] != '.') { + _basename += '.'; + } set_filename(page->get_group(), _basename); _shadow_image.make_shadow_image(_basename); diff --git a/pandatool/src/egg-palettize/palettizer.cxx b/pandatool/src/egg-palettize/palettizer.cxx index ef65ee3ee2..f9c039fe23 100644 --- a/pandatool/src/egg-palettize/palettizer.cxx +++ b/pandatool/src/egg-palettize/palettizer.cxx @@ -24,15 +24,15 @@ #include "filenameUnifier.h" #include "textureMemoryCounter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "pnmImage.h" +#include "pnmFileTypeRegistry.h" +#include "pnmFileType.h" +#include "eggData.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "indent.h" Palettizer *pal = (Palettizer *)NULL; @@ -41,11 +41,12 @@ Palettizer *pal = (Palettizer *)NULL; // allows us to easily update egg-palettize to write out additional // information to its pi file, without having it increment the bam // version number for all bam and boo files anywhere in the world. -int Palettizer::_pi_version = 11; +int Palettizer::_pi_version = 12; // Updated to version 8 on 3/20/03 to remove extensions from texture key names. // Updated to version 9 on 4/13/03 to add a few properties in various places. // Updated to version 10 on 4/15/03 to add _alpha_file_channel. -// Updated to version 11 on 4/30/03 to add TextureReference::_tref_name +// Updated to version 11 on 4/30/03 to add TextureReference::_tref_name. +// Updated to version 12 on 9/11/03 to add _generated_image_pattern. int Palettizer::_min_pi_version = 8; // Dropped support for versions 7 and below on 7/14/03. @@ -99,6 +100,7 @@ public: //////////////////////////////////////////////////////////////////// Palettizer:: Palettizer() { + _generated_image_pattern = "%g_palette_%p_%i"; _map_dirname = "%g"; _shadow_dirname = "shadow"; _margin = 2; @@ -137,6 +139,7 @@ report_pi() const { cout << "\nparams\n" + << " generated image pattern: " << _generated_image_pattern << "\n" << " map directory: " << _map_dirname << "\n" << " shadow directory: " << FilenameUnifier::make_user_filename(_shadow_dirname) << "\n" @@ -303,7 +306,7 @@ report_statistics() const { // matching textures and egg files. //////////////////////////////////////////////////////////////////// void Palettizer:: -read_txa_file(const Filename &txa_filename) { +read_txa_file(istream &txa_file, const string &txa_filename) { // Clear out the group dependencies, in preparation for reading them // again from the .txa file. Groups::iterator gi; @@ -316,7 +319,7 @@ read_txa_file(const Filename &txa_filename) { _shadow_color_type = (PNMFileType *)NULL; _shadow_alpha_type = (PNMFileType *)NULL; - if (!_txa_file.read(txa_filename)) { + if (!_txa_file.read(txa_file, txa_filename)) { exit(1); } @@ -883,6 +886,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) { TypedWritable::write_datagram(writer, datagram); datagram.add_int32(_pi_version); + datagram.add_string(_generated_image_pattern); datagram.add_string(_map_dirname); datagram.add_string(FilenameUnifier::make_bam_filename(_shadow_dirname)); datagram.add_string(FilenameUnifier::make_bam_filename(_rel_dirname)); @@ -1016,6 +1020,9 @@ fillin(DatagramIterator &scan, BamReader *manager) { TypedWritable::fillin(scan, manager); _read_pi_version = scan.get_int32(); + if (_read_pi_version >= 12) { + _generated_image_pattern = scan.get_string(); + } _map_dirname = scan.get_string(); _shadow_dirname = FilenameUnifier::get_bam_filename(scan.get_string()); _rel_dirname = FilenameUnifier::get_bam_filename(scan.get_string()); diff --git a/pandatool/src/egg-palettize/palettizer.h b/pandatool/src/egg-palettize/palettizer.h index 976018ce35..7bf2107d35 100644 --- a/pandatool/src/egg-palettize/palettizer.h +++ b/pandatool/src/egg-palettize/palettizer.h @@ -51,7 +51,7 @@ public: void report_pi() const; void report_statistics() const; - void read_txa_file(const Filename &txa_filename); + void read_txa_file(istream &txa_file, const string &txa_filename); void all_params_set(); void process_command_line_eggs(bool force_texture_read, const Filename &state_filename); void process_all(bool force_texture_read, const Filename &state_filename); @@ -95,6 +95,7 @@ public: // The following parameter values specifically relate to textures // and palettes. These values are stored in the bam file for future // reference. + string _generated_image_pattern; string _map_dirname; Filename _shadow_dirname; Filename _rel_dirname; diff --git a/pandatool/src/egg-palettize/sourceTextureImage.cxx b/pandatool/src/egg-palettize/sourceTextureImage.cxx index d75ca4d7ca..3dce048ee0 100644 --- a/pandatool/src/egg-palettize/sourceTextureImage.cxx +++ b/pandatool/src/egg-palettize/sourceTextureImage.cxx @@ -20,11 +20,11 @@ #include "textureImage.h" #include "filenameUnifier.h" -#include -#include -#include -#include -#include +#include "pnmImageHeader.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" TypeHandle SourceTextureImage::_type_handle; diff --git a/pandatool/src/egg-palettize/sourceTextureImage.h b/pandatool/src/egg-palettize/sourceTextureImage.h index 9ef568615b..98efe9071e 100644 --- a/pandatool/src/egg-palettize/sourceTextureImage.h +++ b/pandatool/src/egg-palettize/sourceTextureImage.h @@ -19,7 +19,7 @@ #ifndef SOURCETEXTUREIMAGE_H #define SOURCETEXTUREIMAGE_H -#include +#include "pandatoolbase.h" #include "imageFile.h" diff --git a/pandatool/src/egg-palettize/txaFile.cxx b/pandatool/src/egg-palettize/txaFile.cxx index 0f4f613f3c..c8812cebb0 100644 --- a/pandatool/src/egg-palettize/txaFile.cxx +++ b/pandatool/src/egg-palettize/txaFile.cxx @@ -22,8 +22,8 @@ #include "paletteGroup.h" #include "textureImage.h" -#include -#include +#include "notify.h" +#include "pnmFileTypeRegistry.h" //////////////////////////////////////////////////////////////////// // Function: TxaFile::Constructor @@ -37,23 +37,16 @@ TxaFile() { //////////////////////////////////////////////////////////////////// // Function: TxaFile::read // Access: Public -// Description: Reads the indicated .txa filename, and returns true +// Description: Reads the indicated stream, and returns true // if successful, or false if there is an error. //////////////////////////////////////////////////////////////////// bool TxaFile:: -read(Filename filename) { - filename.set_text(); - ifstream in; - if (!filename.open_read(in)) { - nout << "Unable to open " << filename << "\n"; - return false; - } - +read(istream &in, const string &filename) { string line; - getline(in, line); int line_number = 1; - while (!in.eof() && !in.fail()) { + int ch = get_line_or_semicolon(in, line); + while (ch != EOF || !line.empty()) { bool okflag = true; // Strip off the comment. @@ -109,9 +102,10 @@ read(Filename filename) { nout << "Error on line " << line_number << " of " << filename << "\n"; return false; } - - getline(in, line); - line_number++; + if (ch == '\n') { + line_number++; + } + ch = get_line_or_semicolon(in, line); } if (!in.eof()) { @@ -179,6 +173,25 @@ write(ostream &out) const { } } +//////////////////////////////////////////////////////////////////// +// Function: TxaFile::get_line_or_semicolon +// Access: Private, Static +// Description: Reads the next line, or the next semicolon-delimited +// phrase, from the indicated input stream. Returns +// the character that marks the end of the line, or EOF +// if the end of file has been reached. +//////////////////////////////////////////////////////////////////// +int TxaFile:: +get_line_or_semicolon(istream &in, string &line) { + line = string(); + int ch = in.get(); + while (ch != EOF && ch != '\n' && ch != ';') { + line += ch; + ch = in.get(); + } + + return ch; +} //////////////////////////////////////////////////////////////////// // Function: TxaFile::parse_group_line diff --git a/pandatool/src/egg-palettize/txaFile.h b/pandatool/src/egg-palettize/txaFile.h index 9036dbd0b4..3d843964ed 100644 --- a/pandatool/src/egg-palettize/txaFile.h +++ b/pandatool/src/egg-palettize/txaFile.h @@ -19,12 +19,12 @@ #ifndef TXAFILE_H #define TXAFILE_H -#include +#include "pandatoolbase.h" #include "txaLine.h" -#include -#include +#include "filename.h" +#include "vector_string.h" #include "pvector.h" @@ -38,7 +38,7 @@ class TxaFile { public: TxaFile(); - bool read(Filename filename); + bool read(istream &in, const string &filename); bool match_egg(EggFile *egg_file) const; bool match_texture(TextureImage *texture) const; @@ -46,6 +46,8 @@ public: void write(ostream &out) const; private: + static int get_line_or_semicolon(istream &in, string &line); + bool parse_group_line(const vector_string &words); bool parse_palette_line(const vector_string &words); bool parse_margin_line(const vector_string &words);