home *** CD-ROM | disk | FTP | other *** search
- /**
- **
- ** NUMPIC.POC - Ways to convert a numbered sequence of picture files
- ** to a flic and back. Also a way to delete the numbered sequence of
- ** pictures when you're done.
- **
- **/
-
- #pragma poco library "pdracces.poe" // extended picture I/O library
- #include <errcodes.h>
-
- #define NO_DIALOG 0 // Parameter to pdraccess options routine
- #define DO_DIALOG 1 // Parameter to pdraccess options routine
-
- /*----------------------------------------------------------------------------
- * dialog strings, menu choices, etc...
- *--------------------------------------------------------------------------*/
-
- char basename_prompt[] = "Base name of numbered pictures?";
- char delete_basename_prompt[] = "Base name of numbered files?";
- char rgbname_prompt[] = "Name of (RGB) pic to load?";
- char dirfile_prompt[] = "Choose file of the correct type in directory:";
-
- char replace_changes_prompt[] = "Okay to discard current flic?\n"
- "(You have %d unsaved changes)"
- ;
- char change_flic_size_prompt[] = "Force flic size to picture size?\n\n"
- "(Current flic size is %d x %d,\n"
- "input picture size is %d x %d.)\n"
- ;
-
- char menu_prompt[] = "Convert between Flic and Pictures";
- char *menu_choices[] =
- {
- " Save Flic as Pics",
- " Load Pics as Flic",
- " Delete Numbered Files",
- " Load Single (RGB) Pic",
- " Load All in Directory",
- " Exit",
- };
-
- enum {MU_EXIT, MU_SAVE, MU_LOAD, MU_DELETE, MU_LOAD1, MU_LOAD_DIR};
-
- char load_prompt[] = "Found %d pictures.\n\n"
- "The pictures may be appended to the end of the "
- "current flic, inserted following the current frame, "
- "or entirely replace the current flic. "
- "\n\n"
- "Please select load option:\n"
- ;
- char *load_choices[] = {"Append", "Insert", "Replace", "Cancel"};
- enum {LOAD_APPEND=1, LOAD_INSERT, LOAD_REPLACE, LOAD_CANCEL};
-
-
- char pdr_prompt[] = "Please select output format:";
- char *pdr_choices[] = {"GIF", "PCX", "TIFF", "Targa", "Macintosh Pict",
- "Windows Bitmap", "Cancel"};
- char *pdr_names[] = {"GIF.PDR", "PCX.PDR", "TIFF.PDR", "TARGA.PDR",
- "PICT.PDR", "BMP.PDR"};
- char *pdr_suffixes[] = {".GIF", ".PCX", ".TIF", ".TGA", ".PCT", ".BMP"};
-
- char *start_of_final_digits(char *pt)
- /***********************************************************************
- * returns pointer to the start of the ending number in the string.
- ***********************************************************************/
- {
- char c;
- int len;
- int i;
-
- i = len = strlen(pt);
- pt += len;
- while (--i >= 0) {
- c = *(--pt);
- if (!(c >= '0' && c <= '9'))
- return(pt+1);
- }
- return pt;
- }
-
-
- int get_num_name(char *name)
- /***********************************************************************
- * Return the number embedded in the "file" portion of a file-name
- * (as opposed to the directory or the suffix.) Return -1 if none.
- ***********************************************************************/
- {
- char *pt;
- char dev[4],dir[70],file[10],suff[5];
-
- fnsplit(name,dev,dir,file,suff);
- if ((pt = start_of_final_digits(file)) == file)
- return(-1);
- return(atoi(pt));
- }
-
- int count_digits(int num)
- /***********************************************************************
- * Return number of digits (base 10) in number.
- ***********************************************************************/
- {
- int digits = 1;
-
- while (num > 10) {
- ++digits;
- num /= 10;
- }
- return(digits);
- }
-
- void make_num_name(char *buf, char *name, int num, int digits)
- /***********************************************************************
- * Given a full file name (device, path, file, suffix), a number,
- * and a minimum count of digits, make a name with the number
- * embedded in the last parts of the 'file' portion of the name.
- * Parameters:
- * char *buf; where to put the numbered name
- * char *name; the original name.
- * int num; the number.
- * int digits; minimum amount of digits to use.
- * Example:
- * make_num_name(buf, "c:\pics\sample.gif", 16, 3)
- * leaves "c:\pics\sampl016.gif" in buf.
- ***********************************************************************/
- {
- char dev[4],dir[70],file[10],suff[5];
- char nfile[10];
- int diglen;
- char *pt;
-
- fnsplit(name,dev,dir,file,suff); // split file into component parts
- if (count_digits(num)>digits) // if number too big override digits
- digits = count_digits(num);
- pt = start_of_final_digits(file);
- diglen = strlen(pt); // find out how many digits already in file name
- if (diglen < digits) { // if less than needed truncate file name
- file[8-digits] = 0;
- diglen = digits;
- } else { // Otherwise truncate at first digit
- *pt = 0;
- }
- sprintf(nfile,"%s%0*d", file, diglen, num);
- fnmerge(buf,dev,dir,nfile,suff);
- }
-
- ErrCode set_up_for_output(char *name)
- /***********************************************************************
- * find and load the pdr to handle the output format, get output options.
- * we try to figure out the pdr name from the basename filetype, but
- * if that doesn't work (eg, if there is no suffix on the basename),
- * we prompt the user for the output format using Qmenu.
- * after a pdr is loaded to handle the output, we check whether output
- * options are supported by the pdr, and if so, we call the pdr's
- * options preset dialog.
- **********************************************************************/
- {
- ErrCode err;
- int thechoice;
- char *pdrname;
- char dev[4],dir[70],file[10],suff[5];
-
- if (Success > (err = PicDriverFindLoad(name))) {
- thechoice = Qmenu(pdr_choices, Array_els(pdr_choices), pdr_prompt);
- if (--thechoice < 0) // convert choice # to array index,
- return Err_abort; // if < 0, user picked Cancel or right-clicked
- if (Success > (err = PicDriverLoad(pdr_names[thechoice]))) {
- return Qerror(err, "Cannot load picture driver %s",pdr_names[thechoice]);
- }
- /* If they've picked a driver from list, force suffix to match. */
- fnsplit(name,dev,dir,file,suff); // split file into component parts
- fnmerge(name,dev,dir,file,pdr_suffixes[thechoice]);
- }
-
- if (PicPdrHasOptions()) {
- if (Success > (err = PicPdrOptionsPreset(DO_DIALOG, 0)))
- return err;
- }
-
- return Success;
- }
-
- void save_pics(char *name)
- /***********************************************************************
- * Save one picture for each frame in current flic.
- ***********************************************************************/
- {
- int i;
- int count;
- char nbuf[PATH_SIZE];
- char suffix[5];
- ErrCode err;
- int min, max;
-
- // Go load the appropriate pdr for outputting the pictures...
-
- if (Success > (err = set_up_for_output(name))) {
- return;
- }
-
- // Set up the loop control...
-
- count = GetFrameCount();
-
- if ((min = get_num_name(name)) < 0)
- min = 1;
- max = min + count - 1;
-
- // Output the pictures...
-
- for (i = min; i <= max; ++i) {
- make_num_name(nbuf,name,i,count_digits(max)); // make up file name
- printf("Saving %s", nbuf); // Put up status line
- if (Success > (err = PicSave(nbuf, NULL))) {
- Qerror(err, "Couldn't save %s", nbuf);
- return;
- }
- NextFrame();
- }
-
- unprintf(); // Get rid of status line
- }
-
- Boolean fexists(char *name)
- /***********************************************************************
- * See whether a file exists.
- ***********************************************************************/
- {
- FILE *f;
-
- if ((f = fopen(name, "rb")) != NULL) {
- fclose(f);
- return TRUE;
- }
- else
- return FALSE;
- }
-
- int count_files(char *base_name)
- /***********************************************************************
- * Count up the number of files starting at base_name and
- * numbered sequentially.
- ***********************************************************************/
- {
- char nbuf[PATH_SIZE];
- int count = 0;
- int base = get_num_name(base_name);
-
- for (;;)
- {
- make_num_name(nbuf, base_name,base+count,0);
- if (!fexists(nbuf))
- break;
- ++count;
- }
- return count;
- }
-
- Boolean report_about_error(ErrCode err, char *name, int cur_pos, int total)
- /***********************************************************************
- * Tell user had error and ask if want to continue.
- ***********************************************************************/
- {
- int temp;
-
- Qerror(err, "Can't load %s (%d of %d)", name, cur_pos+1, total);
- temp = total - cur_pos - 1;
- if (temp > 0)
- {
- if (!Qquestion("Continue loading other %d Pics?", temp))
- return FALSE;
- }
- return TRUE;
- }
-
- void load_pics(char *base_name)
- /***********************************************************************
- * Load up a bunch of consecutively numbered files into the flic.
- ***********************************************************************/
- {
- int i;
- int count;
- int curframe;
- int thechoice;
- char nbuf[PATH_SIZE];
- int base;
- int flicw, flich;
- int picw, pich, picdepth;
- ErrCode err;
- int temp;
-
- base = get_num_name(base_name);
- count = count_files(base_name);
-
- // Get the picture size info for the first pic. This ensures that the
- // file exists, and that a pdr can be found by the pdraccess routines to
- // process the pictures.
-
- if (Success > (err = PicGetSize(base_name, &picw, &pich, &picdepth))) {
- Qerror(err, "Cannot load %s", base_name);
- return;
- }
-
- // Tell the user how many pictures we found to be loaded, and ask for
- // the input option (replace/append/insert). If the replace option is
- // choosen, allow the user to change the size of the new flic, if the size
- // of the pictures differs from the current flic size.
-
- thechoice = Qchoice(load_choices, Array_els(load_choices), load_prompt, count);
-
- switch (thechoice) {
- case LOAD_REPLACE:
- if (0 != (i = GetChangeCount())) {
- if (!Qquestion(replace_changes_prompt, i))
- return;
- }
- GetSize(&flicw, &flich);
- if (flicw != picw || flich != pich) {
- if (Qquestion(change_flic_size_prompt,flicw,flich,picw,pich)) {
- flicw = picw;
- flich = pich;
- }
- }
- ResizeReset(flicw, flich);
- SetFrameCount(count);
- break;
- case LOAD_APPEND:
- SetFrame(GetFrameCount()-1); // move to end of flic
- /* fall thru */
- case LOAD_INSERT:
- InsertFrames(count); // insert enough frames for pics
- NextFrame(); // move to first of inserted frames
- break;
- default:
- return; // User selected Cancel or right-clicked
- }
-
- // If rgb/truecolor data was found in the picture, ask the user for the
- // rgb processing option via the pdracces preset dialog. The choosen
- // option will remain in effect throughout the load sequence.
-
- if (picdepth > 8) {
- if (Success > (err = PicRgbOptionsPreset(DO_DIALOG,0)))
- return;
- }
-
- curframe = 1+GetFrame();
-
- // Load the pictures...
-
- for (i=0; i < count;) {
- make_num_name(nbuf, base_name, base+i, 0);
- printf("Loading %s into frame %d", nbuf, curframe);
- if (Success > (err = PicLoad(nbuf,NULL))) {
- if (!report_about_error(err, nbuf, i, count))
- return;
- }
- if (++i < count) { // don't advance after last picture
- NextFrame(); // (makes multiple insert sequences
- ++curframe; // easier for the user)
- }
- }
-
- unprintf(); // all done, get rid of top status info line
- }
-
- void load_pic_list(char **list, int count)
- /***********************************************************************
- * Load a list of files into flic.
- ***********************************************************************/
- {
- Boolean got_rgb = FALSE;
- char *name;
- int picw, pich, picdepth;
- int i;
- ErrCode err;
-
- SetFrameCount(count);
- SetFrame(0);
- for (i=0; i<count; ++i)
- {
- name = *list++;
- /* First check to see if it's RGB */
- if (Success > (err = PicGetSize(name, &picw, &pich, &picdepth))) {
- Qerror(err, "Cannot load %s", name);
- if (!report_about_error(err, name, i, count))
- return;
- } else {
- /* If RGB (and haven't already) then query how to handle
- * color reduction. */
- if (picdepth > 8 && !got_rgb) {
- if (Success > (err = PicRgbOptionsPreset(DO_DIALOG,0)))
- return;
- got_rgb = TRUE;
- }
- if (Success > (err = PicLoad(name,NULL))) {
- Qerror(err, "Cannot load %s", name);
- if (!report_about_error(err, name, i, count))
- return;
- }
- }
- NextFrame();
- }
- }
-
- void load_dir(char *base_name)
- /***********************************************************************
- * Load a whole directory into flic.
- ***********************************************************************/
- {
- char dev[4],dir[70],file[10],suff[5];
- char wild[10];
- char old_dir[80];
- char **file_list;
- int file_count;
-
-
- fnsplit(base_name, dev, dir, file, suff);
- fnmerge(base_name, dev, dir, "", "");
- /* base name is now dir only. */
- GetDir(old_dir);
- SetDir(base_name);
- sprintf(wild, "*%s", suff);
- if ((file_count = DirList(&file_list, wild, FALSE)) > 0)
- {
- load_pic_list(file_list, file_count);
- FreeDirList(&file_list);
- }
- SetDir(old_dir);
- }
-
- void delete_files(char *base_name)
- /***********************************************************************
- * Delete a bunch of consecutively numbered files.
- ***********************************************************************/
- {
- char nbuf[PATH_SIZE];
- int count;
- int i;
- int base;
-
- base = get_num_name(base_name);
- count = count_files(base_name);
-
- // make extra sure the user wants to do this...
-
- if (!Qquestion("Delete numbered files starting with %s ???", base_name))
- return;
- if (!Qquestion("Are you sure you want to delete all %d"
- " files starting with:\n %s?", count, base_name))
- return;
-
- // okay, go for it.
-
- for (i=0; i < count; ++i)
- {
- make_num_name(nbuf, base_name, base+i, 0);
- DosDelete(nbuf);
- }
- }
-
- Boolean do_one_set(char *base_name)
- /**********************************************************************
- * Put up main program menu and respond to choices. Return FALSE if
- * user selects Exit, TRUE after other commands.
- **********************************************************************/
- {
- int choice;
- ErrCode err;
- char *what;
- char *qfile_header = basename_prompt;
-
- choice = Qmenu(menu_choices, Array_els(menu_choices), menu_prompt);
-
- if (choice == MU_LOAD1) /* It's pretty easy to load one pic. */
- {
- if (Qfile(".TGA;.TIF", "Load",
- base_name, base_name, FALSE, rgbname_prompt))
- {
- if (Success > (err = PicLoad(base_name,NULL)))
- Qerror(err, "Can't load %s", base_name);
- }
- }
- else
- {
- // Figure out what to put on the file selector action button...
-
- switch (choice)
- {
- case MU_SAVE:
- what = "Save";
- break;
- case MU_LOAD:
- what = "Load";
- break;
- case MU_DELETE:
- what = "Delete";
- qfile_header = delete_basename_prompt;
- break;
- case MU_LOAD_DIR:
- what = "Load Dir";
- qfile_header = dirfile_prompt;
- break;
- default:
- return FALSE; // User has chosen Exit or right-clicked.
- }
-
- // Ask user for the base file name...
-
- if (!Qfile(".*", what, base_name, base_name, FALSE, qfile_header))
- return TRUE; // Quit this command, but not program.
-
- // Invoke the requested action...
-
- switch (choice)
- {
- case MU_SAVE:
- save_pics(base_name);
- break;
- case MU_LOAD:
- load_pics(base_name);
- break;
- case MU_DELETE:
- delete_files(base_name);
- break;
- case MU_LOAD_DIR:
- load_dir(base_name);
- break;
- }
- }
-
- return TRUE;
- }
-
-
- void main(void)
- /***********************************************************************
- * Call menu routine above until Exit/Cancel.
- **********************************************************************/
- {
- static char last_path[PATH_SIZE] = "";
-
- GlobalVarGet("numpic_lastpath",last_path);
-
- while (do_one_set(last_path))
- ;
-
- GlobalVarSet("numpic_lastpath",last_path);
- }
-