00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #ifndef ALPHA_LINUX_CXX
00031 # include <unistd.h>
00032 # include <fstream>
00033 # include <cstdio>
00034 # include <cstdlib>
00035 #endif
00036 #include <iostream>
00037 #include <iomanip>
00038 #include <vector>
00039 #include "Flex.h"
00040 #include "utils.h"
00041 #include "exceptions.h"
00042 #include "vgafile.h"
00043 #include "pngio.h"
00044 #include "ibuf8.h"
00045
00046 using std::atoi;
00047 using std::cerr;
00048 using std::cout;
00049 using std::endl;
00050 using std::exit;
00051 using std::ifstream;
00052 using std::ofstream;
00053 using std::istream;
00054 using std::ostream;
00055 using std::setw;
00056 using std::size_t;
00057 using std::strlen;
00058 using std::strncmp;
00059 using std::strcpy;
00060 using std::strcat;
00061 using std::vector;
00062
00063
00064
00065
00066 class Shape_spec
00067 {
00068 public:
00069 char *filename;
00070 int nframes;
00071 bool flat;
00072 bool bycol;
00073 int dim0_tiles;
00074 public:
00075 Shape_spec() : filename(0), nframes(0), flat(false), bycol(false),
00076 dim0_tiles(0)
00077 { }
00078 ~Shape_spec()
00079 { delete filename; }
00080 };
00081 typedef vector<Shape_spec> Shape_specs;
00082
00083
00084
00085
00086
00087 static char *Skip_space
00088 (
00089 char *ptr
00090 )
00091 {
00092 while (isspace(*ptr))
00093 ptr++;
00094 return ptr;
00095 }
00096
00097
00098
00099
00100
00101 static char *Find_space
00102 (
00103 char *ptr
00104 )
00105 {
00106 while (*ptr && !isspace(*ptr))
00107 ptr++;
00108 return ptr;
00109 }
00110
00111
00112
00113
00114
00115 static char *Pass_file_spec
00116 (
00117 char *ptr
00118 )
00119 {
00120 int paren_depth = 0;
00121 while (*ptr && (paren_depth > 0 || !isspace(*ptr)))
00122 {
00123 if (*ptr == '(')
00124 paren_depth++;
00125 else if (*ptr == ')')
00126 paren_depth--;
00127 ptr++;
00128 }
00129 return ptr;
00130 }
00131
00132
00133
00134
00135
00136 static long Get_number
00137 (
00138 int linenum,
00139 char *errmsg,
00140 char *ptr,
00141 char *& endptr
00142 )
00143 {
00144 long num = strtol(ptr, &endptr, 0);
00145 if (endptr == ptr)
00146 {
00147 cerr << "Line " << linenum << ": " << errmsg << endl;
00148 exit(1);
00149 }
00150 endptr = Skip_space(endptr);
00151 return num;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 static char *Get_token
00161 (
00162 int linenum,
00163 char *ptr,
00164 char *& endptr
00165 )
00166 {
00167 ptr = Skip_space(ptr + 7);
00168 endptr = Find_space(ptr);
00169 if (endptr == ptr)
00170 {
00171 cerr << "Line #" << linenum <<
00172 ": Expecting a name" << endl;
00173 exit(1);
00174 }
00175 char sav = *endptr;
00176 *endptr = 0;
00177 char *token = newstrdup(ptr);
00178 *endptr = sav;
00179 return token;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 static void Read_script
00203 (
00204 istream& in,
00205 char *& imagename,
00206 char *& palname,
00207 Shape_specs& specs
00208 )
00209 {
00210 imagename = 0;
00211 specs.resize(0);
00212 specs.reserve(1200);
00213 char buf[1024];
00214 int linenum = 0;
00215 while (!in.eof())
00216 {
00217 ++linenum;
00218 in.get(buf, sizeof(buf));
00219 char delim;
00220 in.get(delim);
00221 if (delim != '\n' && !in.eof())
00222 {
00223 cerr << "Line #" << linenum << " is too long" << endl;
00224 exit(1);
00225 }
00226 if (!buf[0])
00227 continue;
00228 char *ptr = Skip_space(&buf[0]);
00229 if (*ptr == '#')
00230 continue;
00231 char *endptr;
00232 if (strncmp(ptr, "archive", 7) == 0)
00233 {
00234 imagename = Get_token(linenum, ptr, endptr);
00235 continue;
00236 }
00237 if (strncmp(ptr, "palette", 7) == 0)
00238 {
00239 palname = Get_token(linenum, ptr, endptr);
00240 continue;
00241 }
00242
00243 long shnum = Get_number(linenum, "Shape # missing",
00244 ptr, endptr);
00245 if (*endptr != '/')
00246 {
00247 cerr << "Line #" << linenum <<
00248 ": Missing '/' after shape number" << endl;
00249 exit(1);
00250 }
00251 ptr = endptr + 1;
00252 long nframes = Get_number(linenum, "Frame count missing",
00253 ptr, endptr);
00254 if (*endptr != ':')
00255 {
00256 cerr << "Line #" << linenum <<
00257 ": Missing ':' after frame count" << endl;
00258 exit(1);
00259 }
00260 ptr = Skip_space(endptr + 1);
00261 endptr = Pass_file_spec(ptr);
00262 if (endptr == ptr)
00263 {
00264 cerr << "Line #" << linenum <<
00265 ": Missing filename" << endl;
00266 exit(1);
00267 }
00268
00269 char *past_end = *endptr ? Skip_space(endptr + 1) : endptr;
00270 *endptr = 0;
00271 if (shnum >= specs.size())
00272 specs.resize(shnum + 1);
00273 specs[shnum].flat = (strncmp(past_end, "flat", 4) == 0);
00274 specs[shnum].nframes = nframes;
00275 char fname[300], dir[300];
00276 int dim0_cnt;
00277 if (sscanf(ptr, "%[^(](%d %s)", &fname[0], &dim0_cnt, &dir[0])
00278 == 3)
00279 {
00280 if (!specs[shnum].flat)
00281 {
00282 cerr << "Line #" << linenum <<
00283 ": Tiled file not specified 'flat'"
00284 << endl;
00285 exit(1);
00286 }
00287 specs[shnum].dim0_tiles = dim0_cnt;
00288 specs[shnum].bycol = strncmp(dir, "down", 4) == 0;
00289 specs[shnum].filename = strdup(fname);
00290 }
00291 else
00292 specs[shnum].filename = strdup(ptr);
00293 }
00294 }
00295
00296
00297
00298
00299
00300 static void Modify_palette
00301 (
00302 unsigned char *from,
00303
00304 unsigned char *to,
00305 int palsize,
00306 int roff, int goff, int boff,
00307 int r256, int g256, int b256
00308 )
00309 {
00310 int cnt = 3*palsize;
00311 for (int i = 0; i < 3*palsize; )
00312 {
00313 int r = from[i] + roff;
00314
00315 r += (r*r256)/256;
00316 if (r < 0)
00317 r = 0;
00318 if (r > 255)
00319 r = 255;
00320 to[i++] = r;
00321 int g = from[i] + goff;
00322 g += (g*g256)/256;
00323 if (g < 0)
00324 g = 0;
00325 if (g > 255)
00326 g = 255;
00327 to[i++] = g;
00328 int b = from[i] + boff;
00329 b += (b*b256)/256;
00330 if (b < 0)
00331 b = 0;
00332 if (b > 255)
00333 b = 255;
00334 to[i++] = b;
00335 }
00336 }
00337
00338
00339
00340
00341
00342 static void Greyify_palette
00343 (
00344 unsigned char *from,
00345
00346 unsigned char *to,
00347 int palsize
00348 )
00349 {
00350 for (int i = 0; i < palsize; i++)
00351 {
00352 int ind = i*3;
00353
00354 int ave = (from[ind] + from[ind + 1] + from[ind + 2])/3;
00355 to[ind] = to[ind + 1] = to[ind + 2] = ave;
00356 }
00357 }
00358
00359
00360
00361
00362
00363 static void Convert_palette63
00364 (
00365 unsigned char *from,
00366 unsigned char *to,
00367
00368 int palsize
00369 )
00370 {
00371 int i;
00372 for (i = 0; i < 3*palsize; i++)
00373 to[i] = from[i]/4;
00374 memset(to + i, 0, 3*256 - i);
00375
00376 }
00377
00378
00379
00380
00381
00382 static void Write_text_palette
00383 (
00384 char *palname,
00385 unsigned char *palette,
00386 int palsize
00387 )
00388 {
00389
00390 char *txtpal = new char[strlen(palname) + 10];
00391 strcpy(txtpal, palname);
00392 strcat(txtpal, ".txt");
00393 cout << "Creating text (Gimp) palette '" << txtpal << "'" << endl;
00394 ofstream pout(txtpal);
00395 pout << "GIMP palette" << endl;
00396 pout << "Palette from Exult's Ipack" << endl;
00397 int i;
00398 for (i = palsize - 1; i > 0; i--)
00399 if (palette[3*i] != 0 || palette[3*i+1] != 0 ||
00400 palette[3*i+2] != 0)
00401 break;
00402 int last_color = i;
00403 for (i = 0; i <= last_color; i++)
00404 {
00405 int r = palette[3*i],
00406 g = palette[3*i + 1],
00407 b = palette[3*i + 2];
00408 pout << setw(3) << r << ' ' << setw(3) << g << ' ' <<
00409 setw(3) << b << endl;
00410 }
00411 pout.close();
00412 delete txtpal;
00413 }
00414
00415 const unsigned char transp = 255;
00416
00417
00418
00419
00420
00421 static void Write_frame
00422 (
00423 char *basename,
00424 int frnum,
00425 Shape_frame *frame,
00426 unsigned char *palette
00427 )
00428 {
00429 assert(frame != 0);
00430 char *fullname = new char[strlen(basename) + 30];
00431 sprintf(fullname, "%s%02d.png", basename, frnum);
00432 cout << "Writing " << fullname << endl;
00433 int w = frame->get_width(), h = frame->get_height();
00434 Image_buffer8 img(w, h);
00435 img.fill8(transp);
00436 frame->paint(&img, frame->get_xleft(), frame->get_yabove());
00437 int xoff = 0, yoff = 0;
00438 if (frame->is_rle())
00439 {
00440 xoff = -frame->get_xright();
00441 yoff = -frame->get_ybelow();
00442 }
00443
00444 if (!Export_png8(fullname, transp, w, h, w, xoff, yoff, img.get_bits(),
00445 palette, 256, true))
00446 throw file_write_exception(fullname);
00447 delete fullname;
00448 }
00449
00450
00451
00452
00453
00454 static void Write_tiled_frames
00455 (
00456 char *filename,
00457 Shape *shape,
00458 int shnum,
00459 bool bycol,
00460
00461 int dim0_cnt,
00462 unsigned char *palette
00463 )
00464 {
00465 assert(shape != 0);
00466 cout << "Writing " << filename << " tiled"
00467 << (bycol ? ", by cols" : ", by rows") << " first" << endl;
00468 int nframes = shape->get_num_frames();
00469
00470 int dim1_cnt = (nframes + dim0_cnt - 1)/dim0_cnt;
00471 int w, h;
00472 if (bycol)
00473 { h = dim0_cnt*8; w = dim1_cnt*8; }
00474 else
00475 { w = dim0_cnt*8; h = dim1_cnt*8; }
00476 Image_buffer8 img(w, h);
00477 img.fill8(transp);
00478 for (int f = 0; f < nframes; f++)
00479 {
00480 Shape_frame *frame = shape->get_frame(f);
00481 if (!frame)
00482 continue;
00483 if (!frame->is_rle() || frame->get_width() != 8 ||
00484 frame->get_height() != 8)
00485 {
00486 cerr << "Can only tile 8x8 flat shapes, but shape "
00487 << shnum << " doesn't qualify" << endl;
00488 exit(1);
00489 }
00490 int x, y;
00491 if (bycol)
00492 { y = f%dim0_cnt; x = f/dim0_cnt; }
00493 else
00494 { x = f%dim0_cnt; y = f/dim0_cnt; }
00495 frame->paint(&img, x*8 + frame->get_xleft(),
00496 y*8 + frame->get_yabove());
00497 }
00498
00499 if (!Export_png8(filename, transp, w, h, w, 0, 0, img.get_bits(),
00500 palette, 256))
00501 throw file_write_exception(filename);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510 void Write_palettes
00511 (
00512 char *palname,
00513 unsigned char *palette,
00514 int palsize
00515 )
00516 {
00517 cout << "Creating new palette file '" << palname <<
00518 "' using first file's palette" << endl;
00519 unsigned char palbuf[3*256];
00520 if (palsize > 256)
00521 palsize = 256;
00522 ofstream out;
00523 U7open(out, palname);
00524 Flex_writer writer(out, "Exult palette by Ipack", 11);
00525
00526 Convert_palette63(palette, &palbuf[0], palsize);
00527 out.write((const char*)&palbuf[0], sizeof(palbuf));
00528 writer.mark_section_done();
00529
00530 Modify_palette(palette, palbuf, palsize, 0, 0, 0, -64, -64, -64);
00531 Convert_palette63(palbuf, palbuf, palsize);
00532 out.write((const char*)&palbuf[0], sizeof(palbuf));
00533 writer.mark_section_done();
00534
00535 Modify_palette(palette, palbuf, palsize, 0, 0, 0, -128, -128, -128);
00536 Convert_palette63(palbuf, palbuf, palsize);
00537 out.write((const char*)&palbuf[0], sizeof(palbuf));
00538 writer.mark_section_done();
00539
00540 Greyify_palette(palette, palbuf, palsize);
00541 Convert_palette63(palbuf, palbuf, palsize);
00542 out.write((const char*)&palbuf[0], sizeof(palbuf));
00543 writer.mark_section_done();
00544
00545 Convert_palette63(palette, palbuf, palsize);
00546 out.write((const char*)&palbuf[0], sizeof(palbuf));
00547 writer.mark_section_done();
00548
00549 Modify_palette(palette, palbuf, palsize, 184, 184, 184, -32, -32, -32);
00550 Convert_palette63(palbuf, palbuf, palsize);
00551 out.write((const char*)&palbuf[0], sizeof(palbuf));
00552 writer.mark_section_done();
00553
00554 Modify_palette(palette, palbuf, palsize, 0, 0, 0, -96, -96, -96);
00555 Convert_palette63(palbuf, palbuf, palsize);
00556 out.write((const char*)&palbuf[0], sizeof(palbuf));
00557 writer.mark_section_done();
00558
00559 Modify_palette(palette, palbuf, palsize, 30, 0, 0, -96, -96, -96);
00560 Convert_palette63(palbuf, palbuf, palsize);
00561 out.write((const char*)&palbuf[0], sizeof(palbuf));
00562 writer.mark_section_done();
00563
00564 Modify_palette(palette, palbuf, palsize, 64, 0, 0, 384, -20, -20);
00565 Convert_palette63(palbuf, palbuf, palsize);
00566 out.write((const char*)&palbuf[0], sizeof(palbuf));
00567 writer.mark_section_done();
00568
00569 Convert_palette63(palette, palbuf, palsize);
00570 out.write((const char*)&palbuf[0], sizeof(palbuf));
00571 writer.mark_section_done();
00572
00573 Modify_palette(palette, palbuf, palsize, 32, 32, 0, 256, 256, -20);
00574 Convert_palette63(palbuf, palbuf, palsize);
00575 out.write((const char*)&palbuf[0], sizeof(palbuf));
00576 writer.mark_section_done();
00577 if (!writer.close())
00578 throw file_write_exception(palname);
00579
00580 Write_text_palette(palname, palette, palsize);
00581 }
00582
00583
00584
00585
00586
00587 static void Write_exult_from_tiles
00588 (
00589 ostream& out,
00590 char *filename,
00591 int nframes,
00592 bool bycol,
00593
00594 int dim0_cnt,
00595 char *palname
00596 )
00597 {
00598 cout << "Reading " << filename << " tiled"
00599 << (bycol ? ", by cols" : ", by rows") << " first" << endl;
00600
00601 int dim1_cnt = (nframes + dim0_cnt - 1)/dim0_cnt;
00602 int needw, needh;
00603 if (bycol)
00604 { needh = dim0_cnt*8; needw = dim1_cnt*8; }
00605 else
00606 { needw = dim0_cnt*8; needh = dim1_cnt*8; }
00607
00608 unsigned long startpos = out.tellp();
00609 int w, h, rowsize, xoff, yoff, palsize;
00610 unsigned char *pixels, *palette;
00611
00612 if (!Import_png8(filename, 255, w, h, rowsize, xoff, yoff,
00613 pixels, palette, palsize))
00614 throw file_read_exception(filename);
00615 if (w < needw || h < needh)
00616 {
00617 cerr << "File " << filename << " image is too small. " <<
00618 needw << 'x' << needh << " required" << endl;
00619 exit(1);
00620 }
00621 for (int frnum = 0; frnum < nframes; frnum++)
00622 {
00623 int x, y;
00624 if (bycol)
00625 { y = frnum%dim0_cnt; x = frnum/dim0_cnt; }
00626 else
00627 { x = frnum%dim0_cnt; y = frnum/dim0_cnt; }
00628 unsigned char *src = pixels + w*8*y + 8*x;
00629 for (int row = 0; row < 8; row++)
00630 {
00631 out.write(reinterpret_cast<char *>(src), 8);
00632 src += w;
00633 }
00634 }
00635 delete pixels;
00636 if (palname)
00637 Write_palettes(palname, palette, palsize);
00638 delete palette;
00639 }
00640
00641
00642
00643
00644
00645 static void Write_exult
00646 (
00647 ostream& out,
00648 char *basename,
00649 int nframes,
00650 bool flat,
00651 char *palname
00652 )
00653 {
00654 Shape shape(nframes);
00655 char *fullname = new char[strlen(basename) + 30];
00656 int frnum;
00657 for (frnum = 0; frnum < nframes; frnum++)
00658 {
00659 sprintf(fullname, "%s%02d.png", basename, frnum);
00660 cout << "Reading " << fullname << endl;
00661 int w, h, rowsize, xoff, yoff, palsize;
00662 unsigned char *pixels, *palette;
00663
00664 if (!Import_png8(fullname, 255, w, h, rowsize, xoff, yoff,
00665 pixels, palette, palsize))
00666 throw file_read_exception(fullname);
00667 int xleft, yabove;
00668 if (flat)
00669 {
00670 xleft = yabove = 8;
00671 if (w != 8 || h != 8 || rowsize != 8)
00672 {
00673 cerr << "Image in '" << fullname <<
00674 "' is not flat" << endl;
00675 exit(1);
00676 }
00677 }
00678 else
00679 {
00680 xleft = w + xoff - 1;
00681 yabove = h + yoff - 1;
00682 }
00683 shape.set_frame(new Shape_frame(pixels,
00684 w, h, xleft, yabove, !flat), frnum);
00685 delete pixels;
00686 if (palname)
00687 {
00688 Write_palettes(palname, palette, palsize);
00689 palname = 0;
00690 }
00691 delete palette;
00692 }
00693 shape.write(out);
00694 delete fullname;
00695 }
00696
00697
00698
00699
00700
00701 static void Create
00702 (
00703 char *imagename,
00704 char *palname,
00705 Shape_specs& specs,
00706 const char *title
00707 )
00708 {
00709 if (palname && U7exists(palname))
00710 {
00711 cout << "Palette file '" << palname <<
00712 "' exists, so we won't overwrite it" << endl;
00713 palname = 0;
00714 }
00715 ofstream out;
00716 U7open(out, imagename);
00717 Flex_writer writer(out, title, specs.size());
00718 for (Shape_specs::const_iterator it = specs.begin();
00719 it != specs.end(); ++it)
00720 {
00721 int shnum = it - specs.begin();
00722 char *basename = (*it).filename;
00723 if (basename)
00724 {
00725 int dim0_cnt = (*it).dim0_tiles;
00726 if (dim0_cnt > 0)
00727 Write_exult_from_tiles(out, basename,
00728 (*it).nframes, (*it).bycol,
00729 (*it).dim0_tiles, palname);
00730 else
00731 Write_exult(out, basename, (*it).nframes,
00732 (*it).flat, palname);
00733 palname = 0;
00734 }
00735 writer.mark_section_done();
00736 }
00737 if (!writer.close())
00738 throw file_write_exception(imagename);
00739 }
00740
00741
00742
00743
00744
00745
00746
00747 static void Update
00748 (
00749 char *imagename,
00750 char *palname,
00751 Shape_specs& specs,
00752 const char *title
00753 )
00754 {
00755 if (palname && U7exists(palname))
00756 {
00757 cout << "Palette file '" << palname <<
00758 "' exists, so we won't overwrite it" << endl;
00759 palname = 0;
00760 }
00761 Flex in(imagename);
00762 int oldcnt = in.number_of_objects();
00763 vector<char *> data(oldcnt);
00764 vector<int> lengths(oldcnt);
00765 int i;
00766 for (i = 0; i < oldcnt; i++)
00767 {
00768 size_t len;
00769 data[i] = in.retrieve(i, len);
00770 lengths[i] = len;
00771 if (!len)
00772 {
00773 delete data[i];
00774 data[i] = 0;
00775 }
00776 }
00777 ofstream out;
00778 U7open(out, imagename);
00779 int newcnt = oldcnt > specs.size() ? oldcnt : specs.size();
00780 Flex_writer writer(out, title, newcnt);
00781 for (i = 0; i < newcnt; i++)
00782 {
00783
00784 if (i < specs.size() && specs[i].filename != 0)
00785 {
00786 Write_exult(out, specs[i].filename,
00787 specs[i].nframes, specs[i].flat, palname);
00788 palname = 0;
00789 }
00790
00791 else if (i < oldcnt && data[i])
00792 out.write(data[i], lengths[i]);
00793 writer.mark_section_done();
00794 }
00795 if (!writer.close())
00796 throw file_write_exception(imagename);
00797 for (i = 0; i < oldcnt; i++)
00798 delete data[i];
00799 }
00800
00801
00802
00803
00804
00805 static void Extract
00806 (
00807 char *imagename,
00808 char *palname,
00809 Shape_specs& specs
00810 )
00811 {
00812 if (!palname)
00813 {
00814 cerr << "No palette name (i.e., 'palettes.flx') given" << endl;
00815 exit(1);
00816 }
00817 U7object pal(palname, 0);
00818 size_t len;
00819 unsigned char *palbuf = (unsigned char *)
00820 pal.retrieve(len);
00821 for (int i = 0; i < len; i++)
00822 palbuf[i] *= 4;
00823 Vga_file ifile(imagename);
00824 for (Shape_specs::const_iterator it = specs.begin();
00825 it != specs.end(); ++it)
00826 {
00827 char *basename = (*it).filename;
00828 if (!basename)
00829 continue;
00830 int shnum = it - specs.begin();
00831 if (shnum >= ifile.get_num_shapes())
00832 {
00833 cerr << "Shape #" << shnum << " > #shapes in file" <<
00834 endl;
00835 continue;
00836 }
00837
00838 Shape *shape = ifile.extract_shape(shnum);
00839 int nframes = shape->get_num_frames();
00840 if (nframes != (*it).nframes)
00841 cerr << "Warning: # frames (" << (*it).nframes <<
00842 ") given for shape " << shnum <<
00843 " doesn't match actual count (" << nframes <<
00844 ")" << endl;
00845 for (int f = 0; f < nframes; f++)
00846 Write_frame(basename, f, shape->get_frame(f), palbuf);
00847 }
00848 delete palbuf;
00849 }
00850
00851
00852
00853
00854
00855 static void Usage()
00856 {
00857 cerr << "Usage: ipack -[x|c|u] script" << endl;
00858 exit(1);
00859 }
00860
00861
00862
00863
00864
00865 int main
00866 (
00867 int argc,
00868 char **argv
00869 )
00870 {
00871 if (argc < 3 || argv[1][0] != '-')
00872 Usage();
00873 char *scriptname = argv[2];
00874 char *imagename = 0, *palname = 0;
00875 Shape_specs specs;
00876 ifstream specin;
00877 try {
00878 U7open(specin, scriptname, true);
00879 } catch (exult_exception& e) {
00880 cerr << e.what() << endl;
00881 exit(1);
00882 }
00883 Read_script(specin, imagename, palname, specs);
00884 if (!imagename)
00885 {
00886 cerr << "No archive name (i.e., 'shapes.vga') given" << endl;
00887 exit(1);
00888 }
00889 specin.close();
00890 switch (argv[1][1])
00891 {
00892 case 'c':
00893 try {
00894 Create(imagename, palname, specs, "Exult image file");
00895 } catch (exult_exception& e){
00896 cerr << e.what() << endl;
00897 exit(1);
00898 }
00899 break;
00900 case 'x':
00901 try {
00902 Extract(imagename, palname, specs);
00903 } catch (exult_exception& e){
00904 cerr << e.what() << endl;
00905 exit(1);
00906 }
00907 break;
00908 case 'u':
00909 try {
00910 Update(imagename, palname, specs, "Exult image file");
00911 } catch (exult_exception& e){
00912 cerr << e.what() << endl;
00913 exit(1);
00914 }
00915 break;
00916 default:
00917 Usage();
00918 }
00919 return 0;
00920 }