00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00036
00037
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
00067
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
00095
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
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
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
00187
00188
00189
00190
00191
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
00202
00203 _remove_egg_list = args;
00204 return true;
00205 }
00206
00207
00208 return EggMultiFilter::handle_args(args);
00209 }
00210
00211
00212
00213
00214
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
00494
00495
00496
00497 void EggPalettize::
00498 run() {
00499
00500
00501
00502
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
00512
00513
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
00541
00542
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
00626
00627
00628
00629 pal->_omit_solitary = _optimal;
00630
00631 pal->all_params_set();
00632
00633
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
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
00658
00659 pal->reset_images();
00660 _all_textures = true;
00661
00662
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
00674
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
00691
00692
00693
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