home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * FLISUMRY.POC: Summarize a flic by reducing frames to postage stamp images.
- *
- * MAINTENANCE:
- * 03/01/91 Ian Lepore
- * Created.
- * 10/15/91 Ian
- * Reworked, now uses new PSTAMP.POE and has more features.
- * 09/17/92 Ian
- * Fixed an off-by-one bug that was being caused by cumulative
- * floating point rounding error when adding offset_to_nextframe.
- * Now a multiply is used instead of cumulative addition.
- ****************************************************************************/
-
- #pragma poco library "pstamp.poe"
- #include "errcodes.h"
-
- /*----------------------------------------------------------------------------
- * the first release of pj/poco didn't include an Err_range error; if
- * errcodes.h hasn't defined it, we'll define it here to a similar error.
- *--------------------------------------------------------------------------*/
-
- #ifndef Err_range
- #define Err_range Err_parameter_range
- #endif
-
- /*----------------------------------------------------------------------------
- * main menu...
- *--------------------------------------------------------------------------*/
-
- char main_curgrid_template[] = "Set Grid (Now %d x %d)";
- char main_curgrid_string[4+sizeof(main_curgrid_template)];
-
- char main_menu_title[] = "Summarize Flic Frames:";
- char *main_menu[] = {
- "Current Flic",
- "Flic from Disk",
- main_curgrid_string,
- "Help",
- "Exit",
- };
-
- /*----------------------------------------------------------------------------
- * grid size menu...
- *--------------------------------------------------------------------------*/
-
- char grid_title[] = "Dimension for summary grid:";
- char *grid_choices[] = {
- "Custom Size",
- "2 x 2",
- "3 x 3",
- "4 x 4",
- "5 x 5",
- "6 x 6",
- "7 x 7",
- "8 x 8",
- "9 x 9",
- "Cancel"
- };
-
- /*----------------------------------------------------------------------------
- * various "are you sure?" prompts...
- *--------------------------------------------------------------------------*/
-
- char replace_flic_prompt[] = "You have %d unsaved changes.\n\n"
- "Okay to discard changes and create a "
- "new flic containing the summary?"
- ;
- char replace_cel_prompt[] = "Okay to discard current contents of Cel/AnimCel?";
- char replace_swap_prompt[] = "Okay to discard current contents of Swap Screen?";
- char disk_flicpath_prompt[] = "Please choose flic to summarize:";
-
- /*----------------------------------------------------------------------------
- * misc stuff...
- *--------------------------------------------------------------------------*/
-
- Boolean is_okay_to_replace_cel = FALSE;
- Boolean is_okay_to_replace_swap = FALSE;
-
- char grid_option_gvar[] = "$flisumry_grid_option";
- char disk_flicpath_gvar[] = "$flisumry_lastpath";
-
- int grid_dimension; // 3 == 3x3 grid, 4 == 4x4, etc.
-
- void do_help(void)
- /*****************************************************************************
- * give a little help on what the program is all about.
- ****************************************************************************/
- {
- Qtext(
-
- "This program summarizes a flic by creating a screen full of small "
- "'postage stamp' images from the flic's frames. It can summarize "
- "the flic currently in memory, placing the results in the swap "
- "screen, or it can summarize a flic stored on disk, placing the "
- "results in the current flic frame."
- "\n\n"
- "When the current flic is summarized, the resulting summary screen "
- "is always the same resolution as the flic itself."
- "\n\n"
- "When a flic "
- "from disk is summarized, it may have different dimensions than the "
- "current flic frame. Thus, you can summarize a disk flic onto a "
- "frame with a larger resolution, and get larger postage stamps "
- "images in the summary."
-
- );
- }
-
- void get_grid_choice(Boolean do_dialog)
- /*****************************************************************************
- * get the user's preference for the postage stamp grid.
- * if the do_dialog flag is true, we ask the user via Qmenu(). if the flag
- * is false, we retrieve the saved setting from the global variable pool.
- * when the user changes the value via the dialog, we store the new value
- * into the global variable for next time we're run.
- ****************************************************************************/
- {
- int option;
- char stored_option[10] = "0";
-
- if (do_dialog) {
- option = Qmenu(grid_choices, Array_els(grid_choices), grid_title);
- if (option == 1) {
- option = grid_dimension;
- Qnumber(&option, 2, 25, "Custom X by X grid, select value of X:");
- if (option < 2 || option > 25) {
- Qerror(Err_range, "Value must be between 2 and 25 inclusive");
- return;
- }
- }
- sprintf(stored_option, "%d", option);
- GlobalVarSet(grid_option_gvar, stored_option);
- } else {
- GlobalVarGet(grid_option_gvar, stored_option);
- option = atoi(stored_option);
- if (option < 2 || option > 25)
- option = 4;
- }
-
- if (option > 0) {
- grid_dimension = option;
- sprintf(main_curgrid_string, main_curgrid_template,
- grid_dimension, grid_dimension);
- }
- }
-
- char *ordinal(int num)
- /*****************************************************************************
- * return the suffix for a number to make the number ordinal.
- ****************************************************************************/
- {
- int idx;
- static char ordsuffix[10];
- static char *suffi[] = {"th","st","nd","rd"};
-
- idx = num % 10;
- if ((num > 10 && num < 20) || idx > 3)
- idx = 0;
- sprintf(ordsuffix,"%d%s", num, suffi[idx]);
- return ordsuffix;
- }
-
- Errcode summarize_current_flic(void)
- /*****************************************************************************
- * summarize the current flic into the swap screen.
- ****************************************************************************/
- {
- Errcode err;
- int dx, dy;
- int dw, dh;
- int sw, sh;
- int linecount;
- int num_pstamps;
- int curpstamp;
- int change_count;
- int num_flic_frames;
- double offset_to_nextframe;
- double curflicframe;
- Screen *swapscrn;
- Screen *picscrn;
-
- if (SwapExists()) {
- if (!is_okay_to_replace_swap) {
- if (!Qquestion(replace_swap_prompt))
- return Err_abort;
- }
- }
- is_okay_to_replace_swap = TRUE; // only ask once during a run
-
- if (1 >= (num_flic_frames = GetFrameCount())) {
- Qtext("Cannot create a summary of a single-frame flic!");
- return Err_reported;
- }
-
- num_pstamps = grid_dimension * grid_dimension;
-
- if (num_pstamps > num_flic_frames)
- num_pstamps = num_flic_frames;
-
- offset_to_nextframe = (double)num_flic_frames / num_pstamps;
- if (offset_to_nextframe < 1.0)
- offset_to_nextframe = 1.0;
-
- SwapClip(); // make a swap screen
-
- picscrn = GetPicScreen();
- swapscrn = GetSwapScreen();
-
- GetScreenSize(picscrn, &dw, &dh);
- dw = (dw / grid_dimension) - 1;
- dh = (dh / grid_dimension) - 1;
-
- curflicframe = 0.0;
- curpstamp = 1;
-
- InitPstampScreen(swapscrn);
-
- for (dy = 0; curpstamp <= num_pstamps; dy += dh) {
- for (dx = 0, linecount = 0; linecount < grid_dimension && curpstamp <= num_pstamps; dx += dw, ++linecount) {
- SetFrame((int)curflicframe);
- printf("Processing frame %d, the %s of %d in the summary",
- (int)curflicframe, ordinal(curpstamp), num_pstamps);
- MakePstamp(picscrn, swapscrn, dx, dy, dw, dh, TRUE);
- ++curpstamp;
- curflicframe += offset_to_nextframe;
- }
- }
-
- CleanupPstampScreen(swapscrn);
-
- Qtext("Summary completed successfully, results are in the swap screen.");
-
- unprintf();
- return err;
- }
-
- int ask_frame_count(int num_cel_frames, int pstamps_per_frame)
- /*****************************************************************************
- * we have more input frames that will fit in one output frame, ask the user
- * how many output frames should appear in the summary.
- ****************************************************************************/
- {
- int full_summary_frame_count;
- int requested_frame_count;
- static char prompt[] = "There are %d input frames. "
- "Summarizing all input frames "
- "will create %d output frames. "
- "If fewer output frames "
- "are selected, some input "
- "frames will be skipped."
- "\n\n"
- "Please choose the number of output frames:"
- ;
- char formatted_prompt[15+sizeof(prompt)];
-
- full_summary_frame_count = (num_cel_frames+pstamps_per_frame-1)/pstamps_per_frame;
-
- sprintf(formatted_prompt, prompt, num_cel_frames, full_summary_frame_count);
-
- requested_frame_count = full_summary_frame_count;
- if (!Qnumber(&requested_frame_count, 1, full_summary_frame_count, formatted_prompt))
- return Err_abort;
-
- if (requested_frame_count > full_summary_frame_count)
- return full_summary_frame_count;
- else
- return requested_frame_count;
-
- }
-
- Errcode summarize_disk_flic(char *flicpath)
- /*****************************************************************************
- * summarize a flic from disk into the current flic.
- ****************************************************************************/
- {
- Errcode err;
- int dx, dy;
- int dw, dh;
- int sw, sh;
- int change_count;
- int linecount;
- int num_output_frames;
- int cur_output_frame;
- int pstamps_per_frame;
- int num_output_pstamps;
- int cur_pstamp;
- int cur_pstamp_within_frame;
- int num_cel_frames;
- double cur_cel_frame;
- double offset_to_nextframe;
- Screen *celscrn;
- Screen *picscrn;
-
- /*------------------------------------------------------------------------
- * ask permission before wiping out the current flic and/or cel.
- *----------------------------------------------------------------------*/
-
- if (0 != (change_count = GetChangeCount())) {
- if (!Qquestion(replace_flic_prompt, change_count))
- return Err_abort;
- }
-
- if (CelExists()) {
- if (!is_okay_to_replace_cel) {
- if (!Qquestion(replace_cel_prompt))
- return Err_abort;
- }
- }
- is_okay_to_replace_cel = TRUE; // only ask permission once
-
- /*------------------------------------------------------------------------
- * ask for the input flic/cel name, then load it as an AnimCel.
- *----------------------------------------------------------------------*/
-
- if (!Qfile(".FL?;.CEL;.*", "Summarize", flicpath, flicpath, FALSE, disk_flicpath_prompt))
- return Err_abort;
-
- if (Success < (err = LoadCel(flicpath))) {
- Qerror(err, "Cannot load flic/cel file '%s'", flicpath);
- err = Err_reported;
- goto CLEANUP_EXIT;
- }
-
- if (1 >= (num_cel_frames = CelFrameCount())) {
- Qtext("Cannot create a summary of a single-frame flic!");
- err = Err_reported;
- goto CLEANUP_EXIT;
- }
-
- /*------------------------------------------------------------------------
- * figure out how many input frames we have, how many postage stamps we
- * can put on one output frame, and how many output frames the user wants.
- *----------------------------------------------------------------------*/
-
- pstamps_per_frame = grid_dimension * grid_dimension;
- cur_output_frame = 0;
-
- if (pstamps_per_frame > num_cel_frames) {
- num_output_frames = 1;
- num_output_pstamps = num_cel_frames;
- } else {
- num_output_frames = ask_frame_count(num_cel_frames, pstamps_per_frame);
- if (num_output_frames < 1) {
- err = Err_abort;
- goto CLEANUP_EXIT;
- }
- num_output_pstamps = num_output_frames * pstamps_per_frame;
- if (num_output_pstamps > num_cel_frames)
- num_output_pstamps = num_cel_frames;
- }
-
- /*------------------------------------------------------------------------
- * Set up the postage stamp sizes and placements, init the output frames.
- *----------------------------------------------------------------------*/
-
- picscrn = GetPicScreen();
- celscrn = GetCelScreen();
-
- SetFrameCount(1); // goto 1st frame, InitPstamp clears it
- InitPstampScreen(picscrn); // and lays in the 6-cube color palette.
- SetFrameCount(num_output_frames); // now clone the right # of copies of it.
-
- cur_cel_frame = 0.0;
- offset_to_nextframe = (double)num_cel_frames / num_output_pstamps;
- if (offset_to_nextframe < 1.0)
- offset_to_nextframe = 1.0;
-
- GetScreenSize(picscrn, &dw, &dh);
- dw = (dw / grid_dimension) - 1;
- dh = (dh / grid_dimension) - 1;
-
- /*------------------------------------------------------------------------
- * build the summary...
- *----------------------------------------------------------------------*/
-
- for (cur_output_frame = 0;
- cur_cel_frame < num_cel_frames;
- ++cur_output_frame) {
-
- InitPstampScreen(picscrn);
-
- for (dy = 0, cur_pstamp_within_frame = 1;
- (cur_pstamp_within_frame <= pstamps_per_frame &&
- cur_cel_frame < num_cel_frames);
- dy += dh) {
-
- for (dx = 0, linecount = 0;
- (linecount < grid_dimension &&
- cur_pstamp_within_frame <= pstamps_per_frame &&
- cur_cel_frame < num_cel_frames);
- dx += dw, ++linecount) {
-
- CelSetFrame((int)cur_cel_frame);
- printf("Processing frame %d, the %s of %d in the summary",
- (int)cur_cel_frame,
- ordinal(cur_pstamp), num_output_pstamps);
- MakePstamp(celscrn, picscrn, dx, dy, dw, dh, TRUE);
- ++cur_pstamp_within_frame;
- ++cur_pstamp;
- cur_cel_frame = cur_pstamp * offset_to_nextframe;
- }
- }
- CleanupPstampScreen(picscrn);
- NextFrame();
- }
-
- CLEANUP_EXIT:
-
- #if __POCO__ < 178 // original Poco version didn't have a CelRelease()
- CelGet(0,0,1,1); // function, so we free the bulk of the resources
- #else // used by the cel we loaded by cutting out a 1-pixel
- CelRelease(); // cel, which hardly uses any resource at all. Later
- #endif // versions of Poco have a proper CelRelease().
-
- unprintf();
- return err;
- }
-
- void main(void)
- /*****************************************************************************
- * drive main menu dialog, dispatch processing of selections.
- ****************************************************************************/
- {
- int option;
- static char last_path[PATH_SIZE] = "";
-
- GlobalVarGet(disk_flicpath_gvar,last_path);
- get_grid_choice(FALSE); // go load saved grid option from global var
-
- do {
- option = Qmenu(main_menu, Array_els(main_menu), main_menu_title);
- switch (option) {
- case 1:
- summarize_current_flic();
- break;
- case 2:
- summarize_disk_flic(last_path);
- break;
- case 3:
- get_grid_choice(TRUE);
- break;
- case 4:
- do_help();
- break;
- default:
- break;
- }
- } while (option > 0);
-
- GlobalVarSet(disk_flicpath_gvar,last_path);
- }