home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / compresn / dvpeg / src1b / jvmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-09  |  30.6 KB  |  890 lines

  1. /*
  2.  * jdmain.c  ver 1.0 May 11, 1992
  3.  
  4.  Panning, shrinking, video card, mode forcing, brightness works
  5.  
  6.  Improvements:
  7.   - on panning check ahead to see if multiple keypress and if mult of one
  8.       type then do a multiple jump
  9.   - do GIF decoding ??
  10.   - write an interface using wildcard file selection to select files
  11.   - allow video mode selection after load first of image?
  12.   - get my name into this #@%% thing somewhere (email addr too)
  13.   - limiting on pallet scaling to stop after one color rails?
  14.   - beep upon completion of picture?
  15.  
  16.  still have to figure out Cirrus card
  17.  can't force ahead b type
  18.  what happens if you force a mode and don't know size??? default to 1024 - dangerous ??
  19.  
  20.  May 30, 1992
  21.   - patch ATI driver (hardcoded a changable value that was changed)
  22.   - fixed VESA modes
  23.   - added ATI hi_color (32,768 color) mode as card #17 - actually sets ati_hi_color flag
  24.   - note FORCED VIDEO MODE defaults to 1024 size (now removed) --- big mistake if its a lower resolution
  25.   - ATI hi_color x size is patched to work with range checking and allow proper page selection
  26.   - added Tseng 4000 ramdac hi-color modes
  27.   - added multiple keypress detection to move multiple steps per draw
  28.   - insert mode into the user list of modes sorts by y size (assume x also increases with x)
  29.   - the user can fill the mode list with 10 of 320 * 200 if he wants - ie no checking
  30.   - took out jquant1 in ?.h file since why bother using it?
  31.   - fixed some erratic functioning in forcevga (doing something funny crossing segment boundary ??? - seems fixed
  32.  
  33. Problems
  34.  - ATI hi_color fix doubles X size therefore paning selection is wrong!!! - check for other problems too
  35.  - panning disabled for ATI hi_color
  36.  - testing mode add card autodetect, user select and return 1 or 0
  37.  - there must be 1 item in the user list of modes or else a up/down arrow will lock machine
  38.       - solve by only running program if there is a list and make detection a seperate program
  39.  - file_mask has a 0x0a (LF) at the end of it which is needed for the fgets() - problem???
  40.  - tried to add gif decompression but had problems between djmaster, cjmaster ie gif jpeg is write only - ah I don't know yet
  41.  
  42. To add
  43.  - cut storage requirements in half for 256 color modes by packing bytes
  44.  - ability to add custom modes (give mode #, resolution after selected card type
  45.  - add ATI test for 1 meg??? or just let the user set and test modes ??
  46.  - make video detection/testing a seperate program and save into a file
  47.  - panning disabled for hi_color
  48.  
  49.  *
  50.  *  first generation JPG viewer
  51.  *
  52.  * This file contains a trivial test user interface for the JPEG decompressor.
  53.  * It should work on any system with Unix- or MS-DOS-style command lines.
  54.  *
  55.  * Two different command line styles are permitted, depending on the
  56.  * compile-time switch TWO_FILE_COMMANDLINE:
  57.  *    djpeg [options]  inputfile outputfile
  58.  *    djpeg [options]  [inputfile]
  59.  * In the second style, output is always to standard output, which you'd
  60.  * normally redirect to a file or pipe to some other program.  Input is
  61.  * either from a named file or from standard input (typically redirected).
  62.  * The second style is convenient on Unix but is unhelpful on systems that
  63.  * don't support pipes.  Also, you MUST use the first style if your system
  64.  * doesn't do binary I/O to stdin/stdout.
  65.  */
  66.  
  67. #include "jinclude.h"
  68. #ifdef INCLUDES_ARE_ANSI
  69. #include <stdlib.h>        /* to declare exit() */
  70. #endif
  71. #ifdef NEED_SIGNAL_CATCHER
  72. #include <signal.h>        /* to declare signal() */
  73. #endif
  74.  
  75.  
  76. #ifdef DONT_USE_B_MODE        /* define mode parameters for fopen() */
  77. #define READ_BINARY    "r"
  78. #define WRITE_BINARY    "w"
  79. #else
  80. #define READ_BINARY    "rb"
  81. #define WRITE_BINARY    "wb"
  82. #endif
  83.  
  84. #ifndef EXIT_FAILURE        /* define exit() codes if not provided */
  85. #define EXIT_FAILURE  1
  86. #endif
  87.  
  88.  
  89. #include "jversion.h"        /* for version message */
  90. #include <conio.h>
  91. #include "jvsetup.h"            /* setup things for all viewer files */
  92.  
  93.  
  94. /*
  95.  * PD version of getopt(3).
  96.  */
  97.  
  98. #include "egetopt.c"
  99.  
  100.  
  101. /*extern unsigned _stklen = 8192; was not a solution for erratic problems */
  102.  
  103.  
  104. /*
  105.  * This list defines the known output image formats
  106.  * (not all of which need be supported by a given version).
  107.  * You can change the default output format by defining DEFAULT_FMT;
  108.  * indeed, you had better do so if you undefine PPM_SUPPORTED.
  109.  */
  110.  
  111. typedef enum {
  112.     FMT_GIF,        /* GIF format */
  113.     FMT_PPM,        /* PPM/PGM (PBMPLUS formats) */
  114.     FMT_RLE,        /* RLE format */
  115.     FMT_TARGA,        /* Targa format */
  116.     FMT_TIFF        /* TIFF format */
  117. } IMAGE_FORMATS;
  118.  
  119.  
  120.  
  121. #ifndef DEFAULT_FMT        /* so can override from CFLAGS in Makefile */
  122. #define DEFAULT_FMT    FMT_PPM
  123. #endif
  124.  
  125.  
  126. /* These static variables are needed by the error routines. */
  127. /*static jmp_buf setjmp_buffer;    /* for return to caller */
  128. static external_methods_ptr emethods; /* needed for access to message_parm */
  129.  
  130. /* buffer pointer for panning if needed/possible */
  131.  
  132. static big_sarray_ptr raw_pic_ptr;        /* pointer to virt. pic. for panning, 3 used for hi_color mode; 1 otherwise */
  133.  
  134.  
  135. int get_key(void);
  136.  
  137.  
  138. /*
  139.  * Signal catcher to ensure that temporary files are removed before aborting.
  140.  * NB: for Amiga Manx C this is actually a global routine named _abort();
  141.  * see -Dsignal_catcher=_abort in CFLAGS.  Talk about bogus...
  142.  */
  143.  
  144. #ifdef NEED_SIGNAL_CATCHER
  145.  
  146. GLOBAL void
  147. signal_catcher (int signum)
  148. {
  149.   emethods->trace_level = 0;    /* turn off trace output */
  150.   (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  151.   exit(EXIT_FAILURE);
  152. }
  153.  
  154. #endif
  155.  
  156.  
  157.  
  158.  
  159. LOCAL void
  160. usage (char * progname)
  161. /* complain about bad command line */
  162. {
  163.   fprintf(stderr, "usage: %s ", progname);
  164.   fprintf(stderr, "[-P] [-S #] [-b] [-h] [-D] [-d] [-m mem]");
  165.   fprintf(stderr, " inputfile\n");
  166.   fprintf(stderr, " 1) Ahead           2) ATI VGA         3) Chips & Tech\n");
  167.   fprintf(stderr, " 4) Everex          5) Oak Tech.       6) Genoa\n");
  168.   fprintf(stderr, " 7) NCR             8) Paradise        9) Trident\n");
  169.   fprintf(stderr, "10) Trident 8900   11) Tseng, Orchid, Genoa, Willow\n");
  170.   fprintf(stderr, "12) Tseng 4000     13) Video 7        14) Cirrus\n");
  171.   fprintf(stderr, "15) Compaq         16) Vesa           17) ATI - hi color\n");
  172.   fprintf(stderr, "18) Tseng - hi color\n");
  173.   exit(EXIT_FAILURE);
  174. }
  175.  
  176.  
  177.  
  178. LOCAL void
  179. help_usage ()
  180. {
  181.     fprintf(stderr, "-P   to disable panning (saves memory)\n");
  182. /*    fprintf(stderr, "-M   to force the video mode requires the BIOS mode # in dec.\n");*/
  183. /*    fprintf(stderr, "-V # force a certain video card\n");*/
  184.     fprintf(stderr, "-b   use cross block smoothing\n");
  185.     fprintf(stderr, "-g   use grayscale output\n");
  186.     fprintf(stderr, "-D   supress dithering in quantization\n");
  187.     fprintf(stderr, "-m # set maximum memory available\n");
  188.     fprintf(stderr, "-d   enable debugging\n");
  189.     fprintf(stderr, "-S # shrink image to 1/# size\n");
  190.     fprintf(stderr, "Viewing funcions:\n");
  191.     fprintf(stderr, "<Pg Up>  brighten         <Pg Dn>  darken\n");
  192.     fprintf(stderr, "<up arrow>  scroll up     <dwn arrow>  scroll down\n");
  193.     fprintf(stderr, "<up, down arrow> multiple hits will move pic. by larger amounts\n");
  194.     fprintf(stderr, "<+> zoom                  <-> shrink image\n");
  195.     fprintf(stderr, "ESC exit the program\n");
  196.     exit(EXIT_FAILURE);
  197. }
  198.  
  199.  
  200. /* This routine is used for any and all trace, debug, or error printouts
  201.  * from the JPEG code.  The parameter is a printf format string; up to 8
  202.  * integer data values for the format string have been stored in the
  203.  * message_parm[] field of the external_methods struct.
  204.  */
  205.  
  206. METHODDEF void
  207. trace_message (const char *msgtext)
  208. {
  209.   fprintf(stderr, msgtext,
  210.       emethods->message_parm[0], emethods->message_parm[1],
  211.       emethods->message_parm[2], emethods->message_parm[3],
  212.       emethods->message_parm[4], emethods->message_parm[5],
  213.       emethods->message_parm[6], emethods->message_parm[7]);
  214.   fprintf(stderr, "\n");    /* there is no \n in the format string! */
  215. }
  216.  
  217. /*
  218.  * The error_exit() routine should not return to its caller.  The default
  219.  * routine calls exit(), but here we assume that we want to return to
  220.  * read_JPEG_data, which has set up a setjmp context for the purpose.
  221.  * You should make sure that the free_all method is called, either within
  222.  * error_exit or after the return to the outer-level routine.
  223.  */
  224.  
  225. METHODDEF void
  226. error_exit (const char *msgtext)
  227. {
  228.   txtmode();
  229.   trace_message(msgtext);    /* report the error message */
  230.   (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  231. /*    fclose(cinfo.input_file);*/
  232.   exit(EXIT_FAILURE);
  233. /*  longjmp(setjmp_buffer, 1);    /* return control to outer routine */
  234. }
  235.  
  236.  
  237.  
  238. /*
  239.  * To accept the image data from decompression, you must define four routines
  240.  * output_init, put_color_map, put_pixel_rows, and output_term.
  241.  *
  242.  * You must understand the distinction between full color output mode
  243.  * (N independent color components) and colormapped output mode (a single
  244.  * output component representing an index into a color map).  You should use
  245.  * colormapped mode to write to a colormapped display screen or output file.
  246.  * Colormapped mode is also useful for reducing grayscale output to a small
  247.  * number of gray levels: when using the 1-pass quantizer on grayscale data,
  248.  * the colormap entries will be evenly spaced from 0 to MAX_JSAMPLE, so you
  249.  * can regard the indexes are directly representing gray levels at reduced
  250.  * precision.  In any other case, you should not depend on the colormap
  251.  * entries having any particular order.
  252.  * To get colormapped output, set cinfo->quantize_colors to TRUE and set
  253.  * cinfo->desired_number_of_colors to the maximum number of entries in the
  254.  * colormap.  This can be done either in your main routine or in
  255.  * d_ui_method_selection.  For grayscale quantization, also set
  256.  * cinfo->two_pass_quantize to FALSE to ensure the 1-pass quantizer is used
  257.  * (presently this is the default, but it may not be so in the future).
  258.  *
  259.  * The output file writing modules (jwrppm.c, jwrgif.c, jwrtarga.c, etc) may be
  260.  * useful examples of what these routines should actually do, although each of
  261.  * them is encrusted with a lot of specialized code for its own file format.
  262.  */
  263.  
  264.  
  265. METHODDEF void
  266. output_init (decompress_info_ptr cinfo)
  267. /* This routine should do any setup required */
  268. {
  269. int i;
  270.         /* find the right video mode */
  271.         /* first if image is > all modes default to largest mode */
  272.         for (i = 0; i < number_modes_in_list; i++)
  273.             if (ok_mode[i].card_ID >= 0) video_mode_used = i;
  274.  
  275.         for (i = number_modes_in_list - 1; i >=0; i--)
  276.         /* fudge the size calculation by 5 pixels for those pics that are slightly bigger than the mode */
  277.             if (video_cards[ok_mode[i].card_ID].vid_mode[ok_mode[i].which_mode].x_size >= cinfo->image_width - 5
  278.                     && video_cards[ok_mode[i].card_ID].vid_mode[ok_mode[i].which_mode].y_size >= cinfo->image_height - 5
  279.                     &&    ok_mode[i].card_ID >= 0)
  280.                 video_mode_used = i;
  281.  
  282. /* check if hi_color is chosen - if so do setup */
  283. if (ok_mode[video_mode_used].card_ID > 16 ){
  284.     enable_pan = 0;
  285.     hi_color = 1;
  286.     cinfo -> quantize_colors = FALSE;
  287.     cinfo -> two_pass_quantize = FALSE;
  288.     }
  289.  
  290. /* now check if panning would be usefull - only iff card is detected and size know */
  291.  
  292.     if (video_cards[ok_mode[video_mode_used].card_ID].vid_mode[ok_mode[video_mode_used].which_mode].y_size >= cinfo->image_height
  293.          && video_cards[ok_mode[video_mode_used].card_ID].vid_mode[ok_mode[video_mode_used].which_mode].x_size >= cinfo->image_width)
  294.          enable_pan = 0;
  295.  
  296.     if (enable_pan){
  297.             raw_pic_ptr = (*cinfo->emethods->request_big_sarray)
  298.                 (cinfo->image_width, cinfo->image_height, 1L);
  299.         printf("Panning enabled.\n");
  300.         }
  301.     else
  302.         printf("Panning not enabled.\n");
  303.  
  304.     printf("size of image = %li, %li\n", cinfo->image_width, cinfo->image_height);
  305.  
  306.  
  307. /* have user select the video mode from the list of working modes */
  308.  
  309.  
  310.     if (hi_color == 0)
  311.         printf("quantizing down to 256 colors\n");
  312.     else
  313.         printf("Hi_color mode being used\r\n");
  314.  
  315.   /* This routine can initialize for output based on the data passed in cinfo.
  316.     * Useful fields include:
  317.     *    image_width, image_height    Pretty obvious, I hope.
  318.     *    data_precision            bits per pixel value; typically 8.
  319.     *    out_color_space            output colorspace previously requested
  320.     *    color_out_comps            number of color components in same
  321.     *    final_out_comps            number of components actually output
  322.     * final_out_comps is 1 if quantize_colors is true, else it is equal to
  323.     * color_out_comps.
  324.     *
  325.     * If you have requested color quantization, the colormap is NOT yet set.
  326.     * You may wish to defer output initialization until put_color_map is called.
  327.     */
  328. }
  329.  
  330.  
  331.  
  332. /*
  333.  * This routine is called if and only if you have set cinfo->quantize_colors
  334.  * to TRUE.  It is given the selected colormap and can complete any required
  335.  * initialization.  This call will occur after output_init and before any
  336.  * calls to put_pixel_rows.  Note that the colormap pointer is also placed
  337.  * in a cinfo field, whence it can be used by put_pixel_rows or output_term.
  338.  * num_colors will be less than or equal to desired_number_of_colors.
  339.  *
  340.  * The colormap data is supplied as a 2-D array of JSAMPLEs, indexed as
  341.  *        JSAMPLE colormap[component][indexvalue]
  342.  * where component runs from 0 to cinfo->color_out_comps-1, and indexvalue
  343.  * runs from 0 to num_colors-1.  Note that this is actually an array of
  344.  * pointers to arrays rather than a true 2D array, since C does not support
  345.  * variable-size multidimensional arrays.
  346.  * JSAMPLE is typically typedef'd as "unsigned char".  If you want your code
  347.  * to be as portable as the JPEG code proper, you should always access JSAMPLE
  348.  * values with the GETJSAMPLE() macro, which will do the right thing if the
  349.  * machine has only signed chars.
  350.  */
  351.  
  352. METHODDEF void
  353. put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
  354. /* Write the color map */
  355. {
  356. int i;
  357.  
  358.  
  359. forcevga(ok_mode[video_mode_used].card_ID);
  360. svgamode(video_cards[ok_mode[video_mode_used].card_ID].vid_mode[ok_mode[video_mode_used].which_mode].mode_number,
  361.             video_cards[ok_mode[video_mode_used].card_ID].vid_mode[ok_mode[video_mode_used].which_mode].x_size);
  362.  
  363. if (hi_color == 0)
  364.     if (colormap != NULL && num_colors <= 256 && cinfo->out_color_space == CS_RGB){
  365. /* Normal case: RGB color map */
  366.         for (i=0; i < num_colors; i++){
  367.             palbuf[i][0] = (GETJSAMPLE(colormap[0][i]) >> 2);
  368.             palbuf[i][1] = (GETJSAMPLE(colormap[1][i]) >> 2);
  369.             palbuf[i][2] = (GETJSAMPLE(colormap[2][i]) >> 2);
  370.             }
  371.         setmany(palbuf,0,256);
  372.         }
  373.     else printf("color map pointer = NULL or > 256 colors or color space != RGB.\n");
  374. }
  375.  
  376.  
  377. /*
  378.  * This function is called repeatedly, with a few more rows of pixels supplied
  379.  * on each call.  With the current JPEG code, some multiple of 8 rows will be
  380.  * passed on each call except the last, but it is extremely bad form to depend
  381.  * on this.  You CAN assume num_rows > 0.
  382.  * The data is supplied in top-to-bottom row order (the standard order within
  383.  * a JPEG file).  If you cannot readily use the data in that order, you'll
  384.  * need an intermediate array to hold the image.  See jwrrle.c for an example
  385.  * of outputting data in bottom-to-top order.
  386.  *
  387.  * The data is supplied as a 3-D array of JSAMPLEs, indexed as
  388.  *        JSAMPLE pixel_data[component][row][column]
  389.  * where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
  390.  * num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
  391.  * left edge of image).  Note that this is actually an array of pointers to
  392.  * pointers to arrays rather than a true 3D array, since C does not support
  393.  * variable-size multidimensional arrays.
  394.  * JSAMPLE is typically typedef'd as "unsigned char".  If you want your code
  395.  * to be as portable as the JPEG code proper, you should always access JSAMPLE
  396.  * values with the GETJSAMPLE() macro, which will do the right thing if the
  397.  * machine has only signed chars.
  398.  *
  399.  * If quantize_colors is true, then there is only one component, and its values
  400.  * are indexes into the previously supplied colormap.  Otherwise the values
  401.  * are actual data in your selected output colorspace.
  402.  */
  403.  
  404.  
  405. METHODDEF void
  406. put_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
  407. /* Write some rows of output data */
  408. {
  409. /*register FILE * outfile = cinfo->output_file;*/
  410. register JSAMPROW ptr0, ptr1, ptr2, output_row;
  411. static  long col;
  412. static    int ati_color_low, ati_color_hi;                    /* ati 15 bit color word for hi_color */
  413. static  int row, gr_col;
  414. static  unsigned int gr_row = 0;  /* warning 1 shot system here -----------*/
  415. static  unsigned int read_row = 0;            /* more 1 shot */
  416. static    int col_cntr=1, row_cntr=1;                /* warning more 1 shot variables */
  417.  
  418. /* note ------ row is not going from 0 to max because it goes in sections ------*/
  419.  
  420. if (hi_color){
  421.     for (row = 0; row < num_rows; row++) {
  422.         ptr0 = pixel_data[0][row];
  423.         ptr1 = pixel_data[1][row];
  424.         ptr2 = pixel_data[2][row];
  425.         if (enable_pan){
  426.             output_row = *((*cinfo->emethods->access_big_sarray)
  427.                 (raw_pic_ptr, read_row, TRUE));
  428.             }
  429.         for (gr_col = col = 0; col < cinfo->image_width; col++){
  430.             ati_color_low = ((GETJSAMPLE(*ptr2) & 0x1f) + (GETJSAMPLE(*ptr1) << 5)) & 0xff;
  431.             ati_color_hi = (((GETJSAMPLE(*ptr1) >> 3) & 0x03) + (GETJSAMPLE(*ptr0) << 2)) & 0x7f;
  432.             if (enable_pan)
  433.                 *output_row++ = ati_color_low + (ati_color_hi << 8);
  434.  
  435. /* removed x range checking */
  436.             if (gr_row < maxy)
  437.                 if (row_cntr == 1 && col_cntr == 1)
  438.                     if (tseng4){
  439.                         point_hi(gr_col++, gr_row, ati_color_low + (ati_color_hi << 8));
  440.                         }
  441.                     else{
  442.                         point(gr_col++, gr_row, ati_color_low);
  443.                         point(gr_col++, gr_row, ati_color_hi);
  444.                         }
  445.             ptr0++;
  446.             ptr1++;
  447.             ptr2++;
  448.             col_cntr = (col_cntr % shrink) + 1;
  449.             }
  450.         if (row_cntr == 1) gr_row++;
  451.         row_cntr = (row_cntr % shrink) + 1;
  452.         }
  453.     }
  454. else
  455.     for (row = 0; row < num_rows; row++) {
  456.         ptr0 = pixel_data[0][row];
  457.         if (enable_pan) output_row = *((*cinfo->emethods->access_big_sarray)
  458.                                 (raw_pic_ptr, read_row++, TRUE));
  459.         for (gr_col = col = 0; col < cinfo->image_width; col++){
  460.             ati_color_low = GETJSAMPLE(*ptr0);
  461.             if (enable_pan) *output_row++ = ati_color_low;
  462.             if (gr_row < maxy && gr_col < maxx)
  463.                 if (row_cntr == 1 && col_cntr == 1)
  464.                     point(gr_col++, gr_row, ati_color_low);
  465.             ptr0++;
  466.             col_cntr = (col_cntr % shrink) + 1;
  467.             }
  468.         if (row_cntr == 1) gr_row++;
  469.         row_cntr = (row_cntr % shrink) + 1;
  470.         }
  471. }
  472.  
  473.  
  474.  
  475. METHODDEF void
  476. output_term (decompress_info_ptr cinfo)
  477. /* Finish up at the end of the output */
  478. {
  479. JSAMPROW output_row;        /* pseudo struct to hold 1 line for drawing */
  480.  
  481. static int
  482.         exit,                    /* exit flag ie on escape */
  483.         x_pos, y_pos,        /*    current upper left x, y position */
  484.         x_max, y_max,        /* maximum video x, y max (counting from 1 */
  485.         x_size, y_size,    /* picture size */
  486.         x, y,                    /* drawing counters */
  487.         old_color_scale,    /* old one to see if its changed */
  488.         color_scale,        /* factor to scale pallete up or down */
  489.         row, col,
  490.         y_delta, x_delta,
  491.         redraw,                /* cmd to force redraw */
  492.         step,                    /* step size (pixels) for pan - first used as a keypress counter*/
  493.         cmd,
  494.         cmd2;
  495.  
  496.  
  497. static unsigned char    pallet[256][3];    /* duplicate pallete */
  498.  
  499. x_size = cinfo->image_width;
  500. y_size = cinfo->image_height;
  501. x_max = video_cards[card_id].vid_mode[video_mode_used].x_size;
  502. y_max = video_cards[card_id].vid_mode[video_mode_used].y_size;
  503. x_pos = y_pos = exit = color_scale = redraw = 0;
  504.  
  505. while(exit == 0){
  506.     old_color_scale = color_scale;
  507.     y_delta = x_delta = redraw = 0;
  508.     step = 1;                                /* assume 1 keypress only */
  509.     cmd = get_key();
  510.     while (kbhit()){
  511.         cmd2 = get_key();                        /* count the number of times a key is hit (for panning) */
  512.         if (cmd2 == cmd) step++;
  513.         if (cmd2 == escape){                        /* if ESC then exit regardless */
  514.             step = 1;
  515.             cmd = escape;
  516.             }
  517.         }
  518.  
  519.     step *= 15;            /* step 15 pixels per keypress */
  520.     switch (cmd){
  521.         case minus:            shrink++;
  522.                                 if (shrink > 4) shrink = 4;    /* limit to 1/4 size */
  523.                                 else redraw = 1;
  524.                                 break;
  525.         case plus:            shrink--;
  526.                                 if (shrink < 1) shrink = 1;    /* limit to 1:1 since can't zoom */
  527.                                 else redraw = 1;
  528.                                 break;
  529.         case page_up:        color_scale += 2;            /* turn up intensity */
  530.                                 break;
  531.         case page_down:    color_scale--;                /* turn down intensity */
  532.                                 break;
  533.         case arrow_up:        if (y_pos - step >= 0)
  534.                                     y_delta = -step;
  535.                                 else
  536.                                     y_delta = -y_pos;        /* move all the way to top */
  537.                                 break;
  538.         case arrow_down:    if (y_pos + step + y_max <= y_size)
  539.                                     y_delta = step;
  540.                                 else
  541.                                     y_delta = y_max - (y_size - y_pos);
  542.                                 break;
  543.         case arrow_left:    if (x_pos - step >= 0)
  544.                                     x_delta = -step;
  545.                                 else
  546.                                     x_delta = -x_pos;
  547.                                 break;
  548.         case arrow_right:    if (x_pos + step + x_max <= x_size)
  549.                                     x_delta = step;
  550.                                 else
  551.                                     x_delta = x_max - (x_size - x_pos);
  552.                                 break;
  553.         case escape:        exit = 1;
  554.                                 break;
  555. /*        default:                exit = 1;*/
  556.         }
  557.     if (exit == 0){
  558.         if (color_scale != old_color_scale){
  559. /*            color_scale %= 200;    /* mod to 100 - ie it will wrap !! */
  560.             if (color_scale > 100) color_scale = 100;
  561.             if (color_scale < -40) color_scale = -40;
  562.             for (x=0; x < 256; x++){
  563.                 pallet[x][0] = palbuf[x][0] * (1 + (float)color_scale / 40);
  564.                 pallet[x][1] = palbuf[x][1] * (1 + (float)color_scale / 40);
  565.                 pallet[x][2] =    palbuf[x][2] * (1 + (float)color_scale / 40);
  566.                 }
  567.             setmany(pallet, 0, 256);
  568.             }
  569.  
  570.         if (enable_pan && ( x_delta != 0 || y_delta != 0 || redraw)){
  571.             x_pos += x_delta;
  572.             y_pos += y_delta;
  573.             if (shrink == 1){
  574.                 for (y=0; y < y_max; y++){
  575.                     output_row = *((*cinfo->emethods->access_big_sarray)
  576.                             (raw_pic_ptr, y+y_pos, FALSE));
  577.                     for (x = 0; x < x_size; x++)
  578.                         if (x > x_pos)
  579.                             point(x-x_pos, y, *output_row++);
  580.                         else
  581.                             *output_row++;
  582.                     }
  583.                 }
  584.             else{        /* now do a shrunk picture */
  585.                 for (y=0; y < y_max; y++){
  586.                     row = y * shrink + y_pos;
  587.                     if (row < y_size){
  588.                         output_row = *((*cinfo->emethods->access_big_sarray)
  589.                                 (raw_pic_ptr, row, FALSE));
  590.                         for (x = 0; x < x_size; x++){
  591.                             col = x * shrink + x_pos;
  592.                             if (x > x_pos && col < x_size)
  593.                                 point(x-x_pos, y, *output_row++);
  594.                             else{
  595.                                 *output_row++;
  596.                                 if (x <= x_pos) point(x-x_pos, y, 0);        /* black ??  if shrouded */
  597.                                 }
  598.                             *output_row++;        /* since its shrunk at least 1 times */
  599.                             if (shrink >= 3) *output_row++;
  600.                             if (shrink == 4) *output_row++;
  601.                             }
  602.                         }
  603.                     }
  604.                 }
  605.             }
  606.         }
  607.   }
  608.   /* This termination routine may not need to do anything. */
  609.   /* Note that the JPEG code will only call it during successful exit; */
  610.   /* if you want it called during error exit, you gotta do that yourself. */
  611. }
  612.  
  613.  
  614.  
  615.  
  616. /*
  617.  * This routine gets control after the JPEG file header has been read;
  618.  * at this point the image size and colorspace are known.
  619.  * The routine must determine what output routines are to be used, and make
  620.  * any decompression parameter changes that are desirable.  For example,
  621.  * if it is found that the JPEG file is grayscale, you might want to do
  622.  * things differently than if it is color.  You can also delay setting
  623.  * quantize_colors and associated options until this point.
  624.  *
  625.  * j_d_defaults initializes out_color_space to CS_RGB.  If you want grayscale
  626.  * output you should set out_color_space to CS_GRAYSCALE.  Note that you can
  627.  * force grayscale output from a color JPEG file (though not vice versa).
  628.  */
  629.  
  630. METHODDEF void
  631. d_ui_method_selection (decompress_info_ptr cinfo)
  632. {
  633.   /* if grayscale input, force grayscale output; */
  634.   /* else leave the output colorspace as set by main routine. */
  635.   if (cinfo->jpeg_color_space == CS_GRAYSCALE)
  636.      cinfo->out_color_space = CS_GRAYSCALE;
  637.  
  638.   /* select output routines */
  639.   cinfo->methods->output_init = output_init;
  640.   cinfo->methods->put_color_map = put_color_map;
  641.   cinfo->methods->put_pixel_rows = put_pixel_rows;
  642.   cinfo->methods->output_term = output_term;
  643.  
  644.   /* select output file format */
  645.   /* not need for showing pictures */
  646. }
  647.  
  648.  
  649.  
  650.  
  651. int get_key(void)
  652. {
  653. int cmd;
  654. if ( (cmd = getch()) == 0) cmd = getch();
  655. return cmd;
  656. }
  657.  
  658.  
  659.  
  660.  
  661. /*
  662.  * The main program.
  663.  */
  664.  
  665. GLOBAL int
  666. main (int argc, char **argv)
  667. {
  668.     struct decompress_info_struct cinfo;
  669.     struct decompress_methods_struct dc_methods;
  670.     struct external_methods_struct e_methods;
  671.     int c;
  672.     int sel_card;            /* sort of general purpose int - used to load video mode list */
  673.     char file_mask[20];    /* mask for file selection */
  674.     FILE *config_file;
  675.     int text_width,        /* text mode width - not used yet */
  676.         text_mode,            /* text mode # - not used */
  677.         sort_mode;            /* sort type for file names - not used yet */
  678.  
  679.  
  680.   /* Initialize the system-dependent method pointers. */
  681.   cinfo.methods = &dc_methods;
  682.   cinfo.emethods = &e_methods;
  683.   jselerror(&e_methods);    /* error/trace message routines */
  684.   jselmemmgr(&e_methods);    /* memory allocation routines */
  685.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  686.  
  687.     enable_pan = 1;    /* default to on */
  688.     shrink = 1;            /* default to normal size */
  689.     hi_color = 0;        /* assume no hi_color */
  690.  
  691.  
  692.     for (c = 0; c < number_modes_in_list; c++)
  693.         ok_mode[c].card_ID = -1;                        /* signal as unused to ensure undefined modes are not used */
  694.  
  695.   /* Now OK to enable signal catcher. */
  696. #ifdef NEED_SIGNAL_CATCHER
  697.   emethods = &e_methods;
  698.   signal(SIGINT, signal_catcher);
  699. #ifdef SIGTERM            /* not all systems have SIGTERM */
  700.   signal(SIGTERM, signal_catcher);
  701. #endif
  702. #endif
  703.  
  704.   /* Set up default JPEG parameters. */
  705.   j_d_defaults(&cinfo, TRUE);
  706. /*  requested_fmt = DEFAULT_FMT;    /* set default output file format */
  707.  
  708. /* for viewer force quantization and 256 colors */
  709.     cinfo.desired_number_of_colors = 256;
  710.     cinfo.quantize_colors = TRUE;
  711.     cinfo.two_pass_quantize = TRUE;
  712.  
  713.   /* Scan command line options, adjust parameters */
  714.  
  715.   while ((c = egetopt(argc, argv, "S:PbgDm:dh")) != EOF)
  716.      switch (c) {
  717.      case 'S':                /* allow a shrink to 1/# of the image */
  718.         if (optarg == NULL){
  719.             help_usage();
  720.             usage(argv[0]);
  721.             }
  722.         if (sscanf(optarg, "%d", &shrink) < 1);
  723.         else shrink = 2;
  724.         if (shrink > 4 || shrink < 1){
  725.             help_usage();
  726.             usage(argv[0]);
  727.             }
  728.         break;
  729.      case 'P':            /* disable panning */
  730.         enable_pan = 0;
  731.         break;
  732.      case 'b':            /* Enable cross-block smoothing. */
  733.         cinfo.do_block_smoothing = TRUE;
  734.         break;
  735.      case 'g':            /* Force grayscale output. */
  736.         cinfo.out_color_space = CS_GRAYSCALE;
  737.         break;
  738.      case 'h':
  739.         help_usage();
  740.         break;
  741.      case 'D':            /* Suppress dithering in color quantization. */
  742.         cinfo.use_dithering = FALSE;
  743.         break;
  744.      case 'm':            /* Maximum memory in Kb (or Mb with 'm'). */
  745.         { long lval;
  746.     char ch = 'x';
  747.  
  748.     if (optarg == NULL)
  749.       usage(argv[0]);
  750.     if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
  751.       usage(argv[0]);
  752.     if (ch == 'm' || ch == 'M')
  753.       lval *= 1000L;
  754.     e_methods.max_memory_to_use = lval * 1000L;
  755.         }
  756.         break;
  757.      case 'd':            /* Debugging. */
  758.         e_methods.trace_level++;
  759.         break;
  760.      case '?':
  761.      default:
  762.         usage(argv[0]);
  763.         break;
  764.      }
  765.  
  766.   /* If -d appeared, print version identification */
  767.   if (e_methods.trace_level > 0)
  768.      fprintf(stderr, "Erics DVPEG viewer, thanks to:\n");
  769.      fprintf(stderr, "Independent JPEG Group, version %s\n%s\n",
  770.          JVERSION, JCOPYRIGHT);
  771.  
  772.  /* Select the input and output files */
  773.  /* not TWO_FILE_COMMANDLINE -- use Unix style */
  774.  
  775.   cinfo.input_file = stdin;    /* default input file */
  776.   cinfo.output_file = stdout;    /* always the output file */
  777.  
  778.     if (optind != argc-1) {
  779.         fprintf(stderr, "%s: need one input file\n", argv[0]);
  780.         usage(argv[0]);
  781.         }
  782.  
  783.     if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  784.         fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  785.         exit(EXIT_FAILURE);
  786.         }
  787.  
  788. /*
  789.   if ((c = getc(cinfo.input_file)) == EOF)
  790.      ERREXIT(cinfo.emethods, "Empty input file");
  791.  
  792.   switch (c) {
  793. #ifdef GIF_SUPPORTED
  794.   case 'G':
  795.      jselrgif(&cinfo);
  796.      break;
  797. #endif
  798. #ifdef PPM_SUPPORTED
  799.   case 'P':
  800.      jselrppm(&cinfo);
  801.      break;
  802. #endif
  803.   default:            /* assume default is jpeg type picture */
  804.  
  805. #ifdef JFIF_SUPPORTED
  806.   jselrjfif(&cinfo);
  807. #else
  808.   You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
  809. #endif
  810. /*     break;
  811.   }
  812.  
  813. if (ungetc(c, cinfo.input_file) == EOF)
  814.      ERREXIT(cinfo.emethods, "ungetc failed");
  815.   */
  816.  
  817.  
  818. /* does the dvpeg.cfg file exist? */
  819. config_file = fopen("dvpeg.cfg", "rb");
  820. if (config_file != NULL){                        /* load the file mode descriptions */
  821.     text_width = getw(config_file);
  822.     text_mode = getw(config_file);
  823.     sort_mode = getw(config_file);
  824.     fgets(file_mask, 20, config_file);
  825.     c = 0;
  826.     while((sel_card = getw(config_file)) != -1){
  827.         if (c >= number_modes_in_list){
  828.             printf("Error in dvpeg.cfg file.  Please delete it and run vidseteup.\r\n");
  829.             exit(-1);
  830.             }
  831.         ok_mode[c].card_ID = sel_card;
  832.         ok_mode[c++].which_mode = getw(config_file);
  833.         }
  834.     fclose(config_file);
  835.     }
  836. else{                    /* no? then autodetect */
  837.     printf("The configuration file does not exist.\r\n");
  838.     printf("Please run vidsetup.exe to select the video modes that you wish to use.\r\n");
  839.     exit(-1);
  840.     }
  841.  
  842.  
  843. /*
  844.  * OK, here is the main function that actually causes everything to happen.
  845.  * We assume here that the JPEG filename is supplied by the caller of this
  846.  * routine, and that all decompression parameters can be default values.
  847.  * The routine returns 1 if successful, 0 if not.
  848.  */
  849.  
  850.   cinfo.output_file = NULL;    /* if no actual output file involved */
  851.  
  852.   /* Here we supply our own error handler; compare to use of standard error
  853.     * handler in the previous write_JPEG_file example.
  854.     */
  855.   emethods = &e_methods;    /* save struct addr for possible access */
  856.   e_methods.error_exit = error_exit; /* supply error-exit routine */
  857.   e_methods.trace_message = trace_message; /* supply trace-message routine */
  858.  
  859.  
  860.   /* If the decompressor requires full-image buffers (for two-pass color
  861.     * quantization or a noninterleaved JPEG file), it will create temporary
  862.     * files for anything that doesn't fit within the maximum-memory setting.
  863.     * You can change the default maximum-memory setting by changing
  864.     * e_methods.max_memory_to_use after jselmemmgr returns.
  865.     * On some systems you may also need to set up a signal handler to
  866.     * ensure that temporary files are deleted if the program is interrupted.
  867.     * (This is most important if you are on MS-DOS and use the jmemdos.c
  868.     * memory manager back end; it will try to grab extended memory for
  869.     * temp files, and that space will NOT be freed automatically.)
  870.     * See jcmain.c or jdmain.c for an example signal handler.
  871.     */
  872.  
  873.  
  874.  
  875.   /* At this point you can modify the default parameters set by j_d_defaults
  876.     * as needed; for example, you can request color quantization or force
  877.     * grayscale output.  See jdmain.c for examples of what you might change.
  878.     */
  879.  
  880.  
  881.     jpeg_decompress(&cinfo);
  882.     txtmode();
  883.  
  884.   /* Nothin' else to do, except close files. */
  885.   /* Here we assume only the input file need be closed. */
  886.   fclose(cinfo.input_file);
  887.  
  888.   return 1;            /* indicate success */
  889. }
  890.