Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/egg-palettize/eggPalettize.cxx

Go to the documentation of this file.
00001 // Filename: eggPalettize.cxx
00002 // Created by:  drose (28Nov00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "eggPalettize.h"
00020 #include "palettizer.h"
00021 #include "eggFile.h"
00022 #include "pal_string_utils.h"
00023 #include "filenameUnifier.h"
00024 
00025 #include "dcast.h"
00026 #include "eggData.h"
00027 #include "bamFile.h"
00028 #include "notify.h"
00029 #include "notifyCategory.h"
00030 #include "notifySeverity.h"
00031 
00032 #include <stdio.h>
00033 
00034 ////////////////////////////////////////////////////////////////////
00035 //     Function: EggPalettize::Constructor
00036 //       Access: Public
00037 //  Description:
00038 ////////////////////////////////////////////////////////////////////
00039 EggPalettize::
00040 EggPalettize() : EggMultiFilter(true) {
00041   set_program_description
00042     ("egg-palettize attempts to pack several texture maps from various models "
00043      "together into one or more palette images, for improved rendering performance "
00044      "and ease of texture management.  It can also resize textures and convert "
00045      "them to another image file format, whether or not they are actually "
00046      "placed on a palette, and can manage some "
00047      "simple texture properties, like mipmapping and rendering "
00048      "format.\n\n"
00049 
00050      "egg-palettize reads a texture attributes file, usually named "
00051      "textures.txa, which contains instructions from the user about "
00052      "resizing particular textures.  Type egg-palettize -H for an "
00053      "introduction to the syntax of this file.\n\n"
00054 
00055      "The palettization information from previous runs is recorded in a file "
00056      "named textures.boo (assuming the attributes file is named "
00057      "textures.txa); a complete record of every egg file and every texture "
00058      "that has been referenced is kept here.  This allows the program "
00059      "to intelligently manage the multiple egg files that may reference "
00060      "the textures in question.");
00061 
00062 
00063   clear_runlines();
00064   add_runline("[opts] attribfile.txa file.egg [file.egg ...]");
00065 
00066   // We always have EggMultiBase's -f on: force complete load.  In
00067   // fact, we use -f for our own purposes, below.
00068   remove_option("f");
00069   _force_complete = true;
00070 
00071   add_option
00072     ("a", "filename", 0,
00073      "Read the indicated file as the .txa file.  The default is textures.txa.",
00074      &EggPalettize::dispatch_filename, &_got_txa_filename, &_txa_filename);
00075 
00076   add_option
00077     ("pi", "", 0,
00078      "Do not process anything, but instead report the detailed palettization "
00079      "information.",
00080      &EggPalettize::dispatch_none, &_report_pi);
00081 
00082   add_option
00083     ("s", "", 0,
00084      "Do not process anything, but report statistics on palette "
00085      "and texture utilization.",
00086      &EggPalettize::dispatch_none, &_report_statistics);
00087 
00088   add_option
00089     ("R", "", 0,
00090      "Remove the named egg files from the previously-generated state data "
00091      "in textures.boo.",
00092      &EggPalettize::dispatch_none, &_remove_eggs);
00093 
00094   // We redefine -d using add_option() instead of redescribe_option()
00095   // so it gets listed along with these other options that relate.
00096   add_option
00097     ("d", "dirname", 0,
00098      "The directory in which to write the palettized egg files.  This is "
00099      "only necessary if more than one egg file is processed at the same "
00100      "time; if it is included, each egg file will be processed and written "
00101      "into the indicated directory.",
00102      &EggPalettize::dispatch_filename, &_got_output_dirname, &_output_dirname);
00103   add_option
00104     ("dm", "dirname", 0,
00105      "The directory in which to place all maps: generated palettes, "
00106      "as well as images which were not placed on palettes "
00107      "(but may have been resized).  If this contains the string %g, "
00108      "this will be replaced with the 'dir' string associated with a "
00109      "palette group; see egg-palettize -H.",
00110      &EggPalettize::dispatch_string, &_got_map_dirname, &_map_dirname);
00111   add_option
00112     ("ds", "dirname", 0,
00113      "The directory to write palette shadow images to.  These are working "
00114      "copies of the palette images, useful when the palette image type is "
00115      "a lossy-compression type like JPEG; you can avoid generational loss "
00116      "of quality on the palette images with each pass through the palettes "
00117      "by storing these extra shadow images in a lossless image type.  This "
00118      "directory is only used if the :shadowtype keyword appears in the .txa "
00119      "file.",
00120      &EggPalettize::dispatch_filename, &_got_shadow_dirname, &_shadow_dirname);
00121   add_option
00122     ("dr", "dirname", 0,
00123      "The directory to make map filenames relative to when writing egg "
00124      "files.  If specified, this should be an initial substring of -dm.",
00125      &EggPalettize::dispatch_filename, &_got_rel_dirname, &_rel_dirname);
00126   add_option
00127     ("g", "group", 0,
00128      "The default palette group that egg files will be assigned to if they "
00129      "are not explicitly assigned to any other group.",
00130      &EggPalettize::dispatch_string, &_got_default_groupname, &_default_groupname);
00131   add_option
00132     ("gdir", "name", 0,
00133      "The \"dir\" string to associate with the default palette group "
00134      "specified with -g, if no other dir name is given in the .txa file.",
00135      &EggPalettize::dispatch_string, &_got_default_groupdir, &_default_groupdir);
00136 
00137   add_option
00138     ("all", "", 0,
00139      "Consider all the textures referenced in all egg files that have "
00140      "ever been palettized, not just the egg files that appear on "
00141      "the command line.",
00142      &EggPalettize::dispatch_none, &_all_textures);
00143   add_option
00144     ("egg", "", 0,
00145      "Regenerate all egg files that need modification, even those that "
00146      "aren't named on the command line.",
00147      &EggPalettize::dispatch_none, &_redo_eggs);
00148   add_option
00149     ("redo", "", 0,
00150      "Force a regeneration of each image from its original source(s).  "
00151      "When used in conjunction with -egg, this also forces each egg file to "
00152      "be regenerated.",
00153      &EggPalettize::dispatch_none, &_redo_all);
00154   add_option
00155     ("opt", "", 0,
00156      "Force an optimal packing.  By default, textures are added to "
00157      "existing palettes without disturbing them, which can lead to "
00158      "suboptimal packing.  Including this switch forces the palettes "
00159      "to be rebuilt if necessary to optimize the packing, but this "
00160      "may invalidate other egg files which share this palette.",
00161      &EggPalettize::dispatch_none, &_optimal);
00162 
00163   // This isn't even implement yet.  Presently, we never lock anyway.
00164   // Dangerous, but hard to implement reliable file locking across
00165   // NFS/Samba and between multiple OS's.
00166   /*
00167   add_option
00168     ("nolock", "", 0,
00169      "Don't attempt to grab a file lock on the .txa file.  Use "
00170      "with extreme caution, as multiple processes running on the same "
00171      ".txa file may overwrite each other.  Use this only if the lock "
00172      "cannot be achieved for some reason.",
00173      &EggPalettize::dispatch_none, &_dont_lock_txa);
00174   */
00175 
00176   add_option
00177     ("H", "", 0,
00178      "Describe the syntax of the attributes file.",
00179      &EggPalettize::dispatch_none, &_describe_input_file);
00180 
00181   _txa_filename = "textures.txa";
00182 }
00183 
00184 
00185 ////////////////////////////////////////////////////////////////////
00186 //     Function: EggPalettize::handle_args
00187 //       Access: Protected, Virtual
00188 //  Description: Does something with the additional arguments on the
00189 //               command line (after all the -options have been
00190 //               parsed).  Returns true if the arguments are good,
00191 //               false otherwise.
00192 ////////////////////////////////////////////////////////////////////
00193 bool EggPalettize::
00194 handle_args(ProgramBase::Args &args) {
00195   if (_describe_input_file) {
00196     describe_input_file();
00197     exit(1);
00198   }
00199 
00200   if (_remove_eggs) {
00201     // If we're removing these egg files from the database, we don't
00202     // want to try to load them up.  Instead, just save the filenames.
00203     _remove_egg_list = args;
00204     return true;
00205   }
00206 
00207   // Otherwise, load the named egg files up normally.
00208   return EggMultiFilter::handle_args(args);
00209 }
00210 
00211 ////////////////////////////////////////////////////////////////////
00212 //     Function: EggPalettize::describe_input_file
00213 //       Access: Public
00214 //  Description:
00215 ////////////////////////////////////////////////////////////////////
00216 void EggPalettize::
00217 describe_input_file() {
00218   nout <<
00219     "An attributes file consists mostly of lines describing desired sizes of "
00220     "texture maps.  The format resembles, but is not identical to, that of "
00221     "the qtess input file.  Examples:\n\n"
00222 
00223     "  texturename.rgb : 64 64\n"
00224     "  texture-a.rgb texture-b.rgb : 32 16 margin 2\n"
00225     "  *.rgb : 50% cont\n"
00226     "  eyelids.rgb : 16 16 omit\n\n"
00227 
00228     "In general, each line consists of one or more filenames (and can "
00229     "contain shell globbing characters like '*' or '?'), and a colon "
00230     "followed by a size request.  For each texture appearing in an egg "
00231     "file, the input list is scanned from the beginning and the first "
00232     "line that matches the filename defines the size of the texture, as "
00233     "well as other properties associated with the texture.\n\n"
00234 
00235     "A size request is most often a pair of numbers, giving a specific x y "
00236     "size of the texture.  A third number may also be supplied, giving a "
00237     "specific number of channels to convert to (for instance, to force an "
00238     "image to a 64x64 grayscale image, set its size to 64 64 1).  "
00239     "Alternatively, a percentage scaling may be specified, e.g. 30%.  The "
00240     "requested size need not be a power of 2.\n\n"
00241 
00242     "Other valid keywords that may be specified on the same line with the "
00243     "texture are:\n\n";
00244 
00245   show_text("  omit", 10,
00246             "This indicates that the texture should not be placed on any "
00247             "palette image.  It may still be resized, and it will in any "
00248             "case be copied into the install directory.\n\n");
00249 
00250   show_text("  margin i", 10,
00251             "This specifies the number of pixels that should be written "
00252             "around the border of the texture when it is placed in a "
00253             "palette image; i is the integer number of pixels.  The "
00254             "use of a margin helps cut down on color bleed "
00255             "from neighboring images.  If the texture does "
00256             "not end up placed in a palette image, the "
00257             "margin is not used.  If not specified, the default margin is "
00258             "used, which is specified by the :margin command (see below).\n\n");
00259 
00260   show_text("  coverage f", 10,
00261             "This parameter specifies the maximum coverage to allow for this "
00262             "particular texture before rejecting it "
00263             "from the palette.  If not specified, the default is "
00264             "specified by the :coverage command (see below).\n\n");
00265 
00266   nout << "  nearest\n"
00267        << "  linear\n";
00268   show_text("  mipmap", 10,
00269             "One of these options may be used to force the texture to use "
00270             "a particular minfilter/magfilter sampling mode.  If this is not "
00271             "specified, the sampling mode specified in the egg file is "
00272             "used.  Textures that use different sampling modes cannot "
00273             "be placed together on the same palette images.\n\n");
00274 
00275   show_text("  rgba", 10,
00276             "This specifies format 'rgba' should be in effect for this "
00277             "particular texture.  Any valid egg texture format, such as "
00278             "rgba, rgba12, rgba8, rgb5, luminance, etc. may be specified.  "
00279             "If nothing is specified, the format specified in the egg file "
00280             "is used.  The format will automatically be downgraded to match "
00281             "the number of channels in the texture image; e.g. rgba will "
00282             "automatically be converted to rgb for a three-channel image.  "
00283             "As with the filter modes above, textures that use different "
00284             "formats cannot be placed together on the same palette "
00285             "images.\n\n");
00286 
00287   show_text("  force-rgba", 10,
00288             "This specifies a particular format, as above, that should be "
00289             "in effect for this texture, but it will not be downgraded to "
00290             "match the number of channels.  As above, any valid egg texture "
00291             "format may be used, e.g. force-rgba12, force-rgb5, etc.\n\n");
00292 
00293   show_text("  generic", 10,
00294             "Specifies that any image format requested by an egg file "
00295             "that requests a particular bitdepth should be replaced by "
00296             "its generic equivalent, e.g. rgba8 should become rgba.\n\n");
00297 
00298   show_text("  (alpha mode)", 10,
00299             "A particular alpha mode may be applied to a texture by naming "
00300             "the alpha mode.  This may be any valid egg alpha mode, e.g. "
00301             "blend, binary, ms, or dual.\n\n");
00302 
00303   show_text("  (image type)", 10,
00304             "A texture may be converted to a particular image type, for "
00305             "instance jpg or rgb, by naming the type.  If present, this "
00306             "overrides the :imagetype command, described below.  As with "
00307             ":imagetype, you may also specify two type names separated "
00308             "by a comma, to indicate that a different file should be written "
00309             "for the color and alpha components.\n\n");
00310 
00311   show_text("  (group name)", 10,
00312             "A texture may also be assigned to a specific group by naming "
00313             "the group.  The groups are defined using the :group command "
00314             "(see below).  Normally, textures are not assigned directly "
00315             "to groups; instead, it is more useful to assign the egg files "
00316             "they are referenced in to groups; see below.\n\n");
00317 
00318   show_text("  cont", 10,
00319             "Normally, a texture file (or egg file) scans the lines in the "
00320             "attributes file from the top, and stops on the first line that "
00321             "matches its name.  If the keyword 'cont' is included on the "
00322             "line, however, the texture will apply the properties given "
00323             "on the line, and then continue scanning.  This trick may be "
00324             "used to specify general parameters for all files while still "
00325             "allowing the texture to match a more specific line below.\n\n");
00326 
00327   nout <<
00328     "The attributes file may also assign egg files to various "
00329     "named palette groups.  The syntax is similar to the above:\n\n"
00330 
00331     "  car-blue.egg : main\n"
00332     "  road.egg house.egg : main\n"
00333     "  plane.egg : phase_2 main\n"
00334     "  *.egg : phase_2\n\n"
00335 
00336     "Any number of egg files may be named on one line, and the set of "
00337     "named egg files may be simultaneously assigned to one or more groups.  "
00338     "Each group must have been previously defined using the :group command "
00339     "(see below).  Each texture that is referenced by a given "
00340     "egg file will be palettized "
00341     "into at least one of the groups assigned to the egg file.\n\n"
00342 
00343     "Finally, there are a number of special commands that may appear in the "
00344     "attributes file; some of these have been alluded to in the above "
00345     "comments.  These commands typically specify global parameters or "
00346     "palettization options.  The command names begin with a colon to "
00347     "distinguish them from other kinds of lines.  Each command must "
00348     "appear on a line by itself.  The commands are:\n\n";
00349 
00350   show_text("  :palette xsize ysize", 10,
00351             "This specifies the size of the palette images to be "
00352             "created.  The default is 512 by 512.\n\n");
00353 
00354   show_text("  :margin msize", 10,
00355             "This specifies the amount of default margin to apply to all "
00356             "textures that are placed within a palette image.  The margin "
00357             "is a number of additional pixels that are written around the "
00358             "texture image to help prevent color bleeding between "
00359             "neighboring images within the same palette.  The default "
00360             "is 2.\n\n");
00361 
00362   show_text("  :coverage area", 10,
00363             "The 'coverage' of a texture refers to the fraction of "
00364             "the area in the texture image that is actually used, according "
00365             "to the UV's that appear in the various egg files.  If a texture's "
00366             "coverage is less than 1, only some of the texture image is used "
00367             "(and only this part will be written to the palette).  If the "
00368             "coverage is greater than 1, the texture repeats that number of "
00369             "times.  A repeating texture may still be palettized by writing "
00370             "the required number of copies into the palette image, according "
00371             "to the coverage area.\n\n"
00372 
00373             "This command specifies the maximum coverage to allow for any "
00374             "texture before rejecting it from the palette.  It may be any "
00375             "floating-point number greater than zero.  Set this to 1 "
00376             "to avoid palettizing repeating textures altogether.  This may "
00377             "also be overridden for a particular texture using the 'coverage' "
00378             "keyword on the texture line.\n\n");
00379 
00380   show_text("  :round fraction fuzz", 10,
00381             "When the coverage area is computed, it may optionally be "
00382             "rounded up to the next sizeable unit before placing the "
00383             "texture within the palette.  This helps reduce constant "
00384             "repalettization caused by slight differences in coverage "
00385             "between egg files.  For instance, say file a.egg references a "
00386             "texture with a coverage of 0.91, and then later file b.egg "
00387             "is discovered to reference the same texture with a coverage of "
00388             "0.92.  If the texture was already palettized with the original "
00389             "coverage of 0.91, it must now be moved in the palette.\n\n"
00390 
00391             "Rounding the coverage area up to some fixed unit reduces this "
00392             "problem.  For instance, if you specified a value 0.5 for "
00393             "fraction in the above command, it would round both of these "
00394             "values up to the next half-unit, or 1.0.\n\n"
00395 
00396             "The second number is a fuzz factor, and should be a small "
00397             "number; if the coverage area is just slightly larger than "
00398             "the last unit (within the fuzz factor), it is rounded down "
00399             "instead of up.  This is intended to prevent UV coordinates "
00400             "that are just slightly out of the range [0, 1] (which happens "
00401             "fairly often) from forcing the palettization area all the "
00402             "way up to the next stop.\n\n"
00403 
00404             "The default if this is unspecified is 0.1 0.01.  That is, "
00405             "round up to the next tenth, unless within a hundredth of the "
00406             "last tenth.  To disable rounding, specify ':round no'.  "
00407             "Rounding is implicitly disabled when you run with the -opt "
00408             "command line option.\n\n");
00409 
00410   show_text("  :remap (never | group | poly)", 10,
00411             "Sometimes two different parts of an egg file may reference "
00412             "different regions of a repeating texture.  For instance, "
00413             "group A may reference UV coordinate values ranging from (0,5) "
00414             "to (1,6), for a coverage of 1.0, while group B references "
00415             "values ranging from (0,2) to (1,4), for a coverage of 2.0.  "
00416             "The maximum coverage used is only 2.0, and thus the texture "
00417             "only needs to appear in the palette twice, but the total range "
00418             "of UV's is from (0,2) to (1,6), causing an apparent coverage "
00419             "of 4.0.\n\n"
00420 
00421             "It's possible for egg-palettize to reduce this kind of mistake "
00422             "by remapping both groups of UV's so that they overlap.  This "
00423             "parameter specifies how this operation should be done.  If "
00424             "the option is 'never', remapping will not be performed; if "
00425             "'group', entire groups will be remapped as a unit, if 'poly', "
00426             "individual polygons within a group may be remapped.  This last "
00427             "option provides the greatest minimization of UV coverage, "
00428             "but possibly at the expense of triangle strips in the resulting "
00429             "model (since some vertices can no longer be shared).\n\n"
00430 
00431             "Sometimes, it may be necessary to be more restrictive on "
00432             "character geometry than on non-character geometry, because "
00433             "the cost of adding additional vertices on characters is "
00434             "greater.  You can specify a different kind of remapping for "
00435             "characters only, by using the keyword 'char' on the same line, "
00436             "e.g. ':remap group char never'.\n\n"
00437 
00438             "The default remap mode for all geometry, character or otherwise, "
00439             "if no remap mode is specified is 'poly'.\n\n");
00440 
00441   show_text("  :imagetype type[,alpha_type]", 10,
00442             "This specifies the default type of image file that should be "
00443             "generated for each palette image and for each unplaced texture "
00444             "copied into the install directory.  This may be overridden for "
00445             "a particular texture by specifying the image type on the "
00446             "texture line.\n\n"
00447 
00448             "If two image type names separate by a comma are given, it means "
00449             "to generate a second file of the second type for the alpha "
00450             "channel, for images that require an alpha channel.  This allows "
00451             "support for image file formats that do not support alpha "
00452             "(for instance, JPEG).\n\n");
00453 
00454   show_text("  :shadowtype type[,alpha_type]", 10,
00455             "When generating palette images, egg-palettize sometimes has to "
00456             "read and write the same palette image repeatedly.  If the "
00457             "palette image is stored in a lossy file format (like JPEG, see "
00458             ":imagetype), this can eventually lead to degradation of the "
00459             "palette images.  As a workaround, egg-palettize can store "
00460             "its working copies of the palette images in lossless shadow "
00461             "images.  Specify this to enable this feature; give it the "
00462             "name of a lossless image file format.  The shadow images will "
00463             "be written to the directory specified by -ds on the command "
00464             "line.\n\n");
00465 
00466   show_text("  :group groupname [dir dirname] [with group1 group2 ...]", 10,
00467             "This defines a palette group, a logical division of textures.  "
00468             "Each texture is assigned to one or more palette groups before "
00469             "being placed in any palette image; the palette images are "
00470             "tied to the groups.\n\n"
00471 
00472             "The optional parameter 'dir' specifies a directory name to "
00473             "associate with this group.  This name is substituted in for "
00474             "the string '%g' when it appears in the map directory name "
00475             "specified on the command line with -dm; this may be used to "
00476             "install textures and palettes into different directories based "
00477             "on the groups they are assigned to.\n\n"
00478 
00479             "Palette groups can also be hierarchically related.  The "
00480             "keyword 'with' specifies any number of groups that this "
00481             "palette group depends on; if a texture has already been "
00482             "assigned to one of this group's dependent groups, it will "
00483             "not need to be assigned to this group.\n\n");
00484 
00485 
00486   nout <<
00487     "Comments may appear freely throughout the file, and are set off by a "
00488     "hash mark (#).\n\n";
00489 }
00490 
00491 
00492 ////////////////////////////////////////////////////////////////////
00493 //     Function: EggPalettize::run
00494 //       Access: Public
00495 //  Description:
00496 ////////////////////////////////////////////////////////////////////
00497 void EggPalettize::
00498 run() {
00499   // Fiddle with the loader severity, so we don't confuse the user
00500   // with spurious "reading" and "writing" messages about the state
00501   // file.  If the severity is currently NS_info (the default), set it
00502   // to NS_warning instead.
00503   Notify *notify = Notify::ptr();
00504   NotifyCategory *loader_cat = notify->get_category(":loader");
00505   if (loader_cat != (NotifyCategory *)NULL &&
00506       loader_cat->get_severity() == NS_info) {
00507     loader_cat->set_severity(NS_warning);
00508   }
00509 
00510   if (!_txa_filename.exists() && !_got_txa_filename) {
00511     // If we did not specify a filename, and the default filename of
00512     // "textures.txa" doesn't exist, try looking in src/maps, as
00513     // another likely possibility.
00514     Filename maybe = _txa_filename;
00515     maybe.set_dirname("src/maps");
00516     if (maybe.exists()) {
00517       _txa_filename = maybe;
00518     }
00519   }
00520 
00521   if (!_txa_filename.exists()) {
00522     nout << FilenameUnifier::make_user_filename(_txa_filename)
00523          << " does not exist; cannot run.\n";
00524     exit(1);
00525   }
00526 
00527   FilenameUnifier::set_txa_filename(_txa_filename);
00528 
00529   Filename state_filename = _txa_filename;
00530   state_filename.set_extension("boo");
00531 
00532   BamFile state_file;
00533 
00534   if (!state_filename.exists()) {
00535     nout << FilenameUnifier::make_user_filename(state_filename)
00536          << " does not exist; starting palettization from scratch.\n";
00537     pal = new Palettizer;
00538 
00539   } else {
00540     // Read the Palettizer object from the Bam file written
00541     // previously.  This will recover all of the state saved from the
00542     // past session.
00543     nout << "Reading " << FilenameUnifier::make_user_filename(state_filename)
00544          << "\n";
00545 
00546     if (!state_file.open_read(state_filename)) {
00547       nout << FilenameUnifier::make_user_filename(state_filename)
00548            << " exists, but cannot be read.  Perhaps you should "
00549            << "remove it so a new one can be created.\n";
00550       exit(1);
00551     }
00552 
00553     TypedWritable *obj = state_file.read_object();
00554     if (obj == (TypedWritable *)NULL || !state_file.resolve()) {
00555       nout << FilenameUnifier::make_user_filename(state_filename)
00556            << " exists, but appears to be corrupt.  Perhaps you "
00557            << "should remove it so a new one can be created.\n";
00558       exit(1);
00559     }
00560 
00561     if (!obj->is_of_type(Palettizer::get_class_type())) {
00562       nout << FilenameUnifier::make_user_filename(state_filename)
00563            << " exists, but does not appear to be "
00564            << "an egg-palettize output file.  Perhaps you "
00565            << "should remove it so a new one can be created.\n";
00566       exit(1);
00567     }
00568 
00569     state_file.close();
00570 
00571     pal = DCAST(Palettizer, obj);
00572 
00573     if (pal->_read_pi_version > pal->_pi_version) {
00574       nout << FilenameUnifier::make_user_filename(state_filename)
00575            << " was written by a more recent version of egg-palettize "
00576            << "than this one.  You will need to update your egg-palettize.\n";
00577       exit(1);
00578     }
00579 
00580     if (pal->_read_pi_version < pal->_min_pi_version) {
00581       nout << FilenameUnifier::make_user_filename(state_filename)
00582            << " was written by an old version of egg-palettize.\n\n"
00583            << "You will need to make undo-pal (or simply remove the file "
00584            << FilenameUnifier::make_user_filename(state_filename)
00585            << " and try again).\n\n";
00586       exit(1);
00587     }
00588   }
00589 
00590   if (_report_pi) {
00591     pal->report_pi();
00592     exit(0);
00593   }
00594 
00595   if (_report_statistics) {
00596     pal->report_statistics();
00597     exit(0);
00598   }
00599 
00600   bool okflag = true;
00601 
00602   pal->read_txa_file(_txa_filename);
00603 
00604   if (_got_default_groupname) {
00605     pal->_default_groupname = _default_groupname;
00606   } else {
00607     pal->_default_groupname = _txa_filename.get_basename_wo_extension();
00608   }
00609 
00610   if (_got_default_groupdir) {
00611     pal->_default_groupdir = _default_groupdir;
00612   }
00613 
00614   if (_got_map_dirname) {
00615     pal->_map_dirname = _map_dirname;
00616   }
00617   if (_got_shadow_dirname) {
00618     pal->_shadow_dirname = _shadow_dirname;
00619   }
00620   if (_got_rel_dirname) {
00621     pal->_rel_dirname = _rel_dirname;
00622     FilenameUnifier::set_rel_dirname(_rel_dirname);
00623   }
00624 
00625   // We only omit solitary textures from palettes if we're running in
00626   // optimal mode.  Otherwise, we're likely to invalidate old egg
00627   // files by changing a texture from solitary to nonsolitary state or
00628   // vice-versa.
00629   pal->_omit_solitary = _optimal;
00630 
00631   pal->all_params_set();
00632 
00633   // Remove any files named for removal.
00634   Args::const_iterator ai;
00635   for (ai = _remove_egg_list.begin(); ai != _remove_egg_list.end(); ++ai) {
00636     Filename filename = (*ai);
00637     pal->remove_egg_file(filename.get_basename());
00638   }
00639 
00640   // And process the egg files named for addition.
00641   string egg_comment = get_exec_command();
00642   Eggs::const_iterator ei;
00643   for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
00644     EggData *egg_data = (*ei);
00645     Filename source_filename = egg_data->get_egg_filename();
00646     Filename dest_filename = get_output_filename(source_filename);
00647     string name = source_filename.get_basename();
00648 
00649     EggFile *egg_file = pal->get_egg_file(name);
00650     egg_file->from_command_line(egg_data, source_filename, dest_filename,
00651                                 egg_comment);
00652 
00653     pal->_command_line_eggs.push_back(egg_file);
00654   }
00655 
00656   if (_optimal) {
00657     // If we're asking for an optimal packing, throw away the old
00658     // packing and start fresh.
00659     pal->reset_images();
00660     _all_textures = true;
00661 
00662     // Also turn off the rounding-up of UV's for this purpose.
00663     pal->_round_uvs = false;
00664   }
00665 
00666   if (_all_textures) {
00667     pal->process_all(_redo_all, state_filename);
00668   } else {
00669     pal->process_command_line_eggs(_redo_all, state_filename);
00670   }
00671 
00672   if (_optimal) {
00673     // If we're asking for optimal packing, this also implies we want
00674     // to resize the big empty palette images down.
00675     pal->optimal_resize();
00676   }
00677 
00678   if (_redo_eggs) {
00679     if (!pal->read_stale_eggs(_redo_all)) {
00680       okflag = false;
00681     }
00682   }
00683 
00684   pal->generate_images(_redo_all);
00685 
00686   if (!pal->write_eggs()) {
00687     okflag = false;
00688   }
00689 
00690   // Make up a temporary filename to write the state file to, then
00691   // move the state file into place.  We do this in case the user
00692   // interrupts us (or we core dump) before we're done; that way we
00693   // won't leave the state file incompletely written.
00694   string dirname = state_filename.get_dirname();
00695   if (dirname.empty()) {
00696     dirname = ".";
00697   }
00698   Filename temp_filename = Filename::temporary(dirname, "pi");
00699 
00700   if (!state_file.open_write(temp_filename) ||
00701       !state_file.write_object(pal)) {
00702     nout << "Unable to write palettization information to "
00703          << FilenameUnifier::make_user_filename(temp_filename)
00704          << "\n";
00705     exit(1);
00706   }
00707 
00708   state_file.close();
00709   state_filename.unlink();
00710   if (!temp_filename.rename_to(state_filename)) {
00711     nout << "Unable to rename temporary file "
00712          << FilenameUnifier::make_user_filename(temp_filename) << " to "
00713          << FilenameUnifier::make_user_filename(state_filename) << "\n";
00714     exit(1);
00715   }
00716 
00717   if (!okflag) {
00718     exit(1);
00719   }
00720 }
00721 
00722 int
00723 main(int argc, char *argv[]) {
00724   EggPalettize prog;
00725   prog.parse_command_line(argc, argv);
00726   prog.run();
00727   return 0;
00728 }
00729 
00730 

Generated on Fri May 2 03:17:40 2003 for Panda-Tool by doxygen1.3