home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / graphics / utility / mgif35s / mgif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-18  |  51.2 KB  |  2,236 lines

  1. /* this version uses flicker */
  2.  
  3. #define V_HIST            /* def for vertical histogram */
  4. #undef DBL_LOOP            /* def for for(x..., for(y... loops */
  5. #undef FULL_SCREEN        /* def to write entire screen, not just wxh */
  6.  
  7. /*
  8.  *    mgif - floyd-steinberg dither (mono) a gif image (.gif)
  9.  *
  10.  *    gif decoder lifted from PBMplus package. flicker adopted from
  11.  *    work by Klaus Pedersen (micro@imada.dk)
  12.  *
  13.  *    history:
  14.  *
  15.  *    90/12/16 1.0 rosenkra    - initial release (posted to c.s.atari.st)
  16.  *
  17.  *    91/1/7 1.1 rosenkra    - change -i to -r
  18.  *                - change -q to -i
  19.  *                - started to add -q (quantize), not complete
  20.  *                - fix bug with zero'ed accumulation arrays
  21.  *                which was being done with every call to
  22.  *                rasterize
  23.  *                - add histogram for each rgb value (eliminate
  24.  *                the "intensity order" histogram, too)
  25.  *                - make UseNTSC global
  26.  *                - fix scan_CM (bug in gemlib read)
  27.  *                - make default -s of 40
  28.  *                - histogram now impacted by -N (NTSC)
  29.  *                - add -f option
  30.  *    91/2/25 1.2 rosenkra    - add -b option
  31.  *                - -i does not print color map. use -i -i
  32.  *    91/6/3 3.0 rosenkra    - major rewrite using "flicker"
  33.  *                - really interactive only now
  34.  *                - ReadGIF now single entry point
  35.  *                - flicker is single entry point
  36.  *                - does lots of image processing (menu)
  37.  *                including size, blur, brighten, log scale,
  38.  *                contrast expansion, median filter
  39.  *    91/6/3 3.2 rosenkra    - add convolutions
  40.  *                - release to usenet
  41.  *    91/6/6 3.3 rosenkra    - add cut, rotate, mirror
  42.  *                - add flicker file write (*.fl)
  43.  *    91/6/9 3.4 rosenkra    - fix some bugs in file write, median, log
  44.  *                scale, etc
  45.  *                - enlarge/shrink by direction
  46.  *                - cut can work beyond screen size
  47.  *                - add support for .pi1 and .pi2 files
  48.  *    91/6/13 3.5 rosenkra    - point coord selection by crosshairs
  49.  *                - add zoom (2x)
  50.  *                - add histogram on screen in flicker screen
  51.  *                - add copy orig<-->new
  52.  */
  53.  
  54. static char *sccsid  = "@(#) mgif.c 3.5 91/6/18 rosenkra\0\0                ";
  55. char        *myname  = "mgif\0\0\0\0\0\0";
  56. char        *version = "mgif 3.5 91/6/18 rosenkra\0\0\0                     ";
  57.  
  58.  
  59. #include <stdio.h>
  60. #include <osbind.h>
  61. #include "mgif.h"
  62.  
  63. #define SCRNSPACE    48256L    /* buffer size for 3 screens (words) */
  64.                 /* leave extra to word-align */
  65.  
  66.  
  67. /*
  68.  *    globals:
  69.  */
  70. uchar_t        CodedGIF[MAXRAW];/* raw LZW coded raster after unblock*/
  71. uchar_t        ColMap[MAPSIZ][3];/* color map we use (global or local)*/
  72. screen_t    ScrnInf;    /* global screen descriptor */
  73. image_t        Id;        /* image id struct */
  74. uchar_t        Raster[MAXIMG];    /* final raster image, ColMap indx */
  75. uchar_t        TransRast[MAXIMG];/* transformed raster image */
  76.  
  77. int        Height,        /* image size */
  78.         Width;
  79. int        NewHeight,    /* transformed image size */
  80.         NewWidth;
  81.  
  82. int        ShowFl = 0;
  83. int        montage = 0;
  84. int        Pi1 = 0;    /* use this on degas files also */
  85. int        Pi2 = 0;
  86. int        Batch = 0;
  87. int        Noise = 0;    /* percentage of random noise */
  88. int        Beta = 0;    /* beta factor for Laplace filter */
  89. int        Verbose = 0;    /* this is VERY verbose... */
  90. int        Inquire = 0;    /* inquire or render */
  91. int        Quantize = 0;    /* quantize to 16 shades */
  92. int        UseNTSC = 0;    /* NTSC equation for lumin */
  93. long        Hist[HISTSIZ];    /* histogram */
  94. int        XUpperLeft = 0,    /* starting pixel (default is 0,0) */
  95.         YUpperLeft = 0;
  96. int           *PScreens;    /* what flicker returns. ptr to 3 screens */
  97.  
  98.  
  99. /*
  100.  *    local functions
  101.  */
  102. int        usage ();
  103. int        draw_image ();
  104. int        cmaptoint ();
  105. int        showfl ();
  106. void        title ();
  107. void        conv_menu ();
  108. void        do_help ();
  109.  
  110.  
  111. /*
  112.  *    external functions
  113.  */
  114. extern long    atol ();        /* from libc */
  115. extern int    ReadGIF ();        /* from readgif.c */
  116. extern int    ReadPI1 ();        /* from readpi.c */
  117. extern int    ReadPI2 ();
  118. extern int     *flicker ();        /* from flicker.c */
  119. extern long    linea0 ();        /* from linea.s */
  120. extern int    linea3 ();
  121. extern int    larger ();        /* from process.c */
  122. extern int    zoom ();
  123. extern int    smaller ();
  124. extern int    cut ();
  125. extern int    rotate ();
  126. extern int    mirror ();
  127. extern int    convolve ();
  128. extern int    blur ();
  129. extern int    median ();
  130. extern int    piksrt ();
  131. extern int    logscale ();
  132. extern int    Log2 ();
  133. extern int    contrast ();
  134. extern int    brighten ();
  135. extern int    invert ();
  136. extern int    threshold ();
  137. extern int    histeq ();
  138. extern int    redistribute ();
  139. extern int    copyrast ();
  140. extern int    do_hist ();        /* from low.c */
  141. extern int    draw_hist ();
  142. extern int    drhhist ();
  143. extern int    drvhist ();
  144. extern int    grid ();
  145. extern int    do_line ();
  146. extern void    xor_line ();
  147. extern void    xor_dash ();
  148. extern int    cursor ();
  149. extern int    clr_cmd ();
  150. extern int    mv_cursor ();
  151. extern int    clr_screen ();
  152. extern long    do_time ();
  153. extern int    check_key ();
  154. extern int    get_key ();
  155. extern int    get_string ();
  156. extern long    get_rkey ();
  157. extern int    get_xypos ();
  158. extern int    wait_key ();
  159. extern int    wait_ms ();
  160. extern int    write_fl ();        /* from file.c */
  161. extern int    read_fl ();
  162.  
  163.  
  164.  
  165. /*------------------------------*/
  166. /*    main            */
  167. /*------------------------------*/
  168. main (argc, argv)
  169. int    argc;
  170. char   *argv[];
  171. {
  172.     long        elapsed;    /* elapsed seconds */
  173.     int        gif_fd;        /* file descriptor */
  174.     char           *ps;
  175.     char           *fname;
  176.     int        ret;
  177.     register long    ii;
  178.     register int   *pscrn;
  179.     int        count;
  180.     int           *scrn;            /* -> first screen for -fl */
  181.  
  182.  
  183.     /*
  184.      *   set defaults...
  185.      */
  186.     Batch = 0;
  187.  
  188.  
  189.  
  190.     /*
  191.      *   parse args...
  192.      */
  193.     for (argc--, argv++; (argc && **argv == '-'); argc--, argv++)
  194.     {
  195.         switch (*(*argv+1))
  196.         {
  197.         case 'f':        /* just show flicker files */
  198.             if (!strncmp (*argv, "-fl", 3))
  199.                 ShowFl++;
  200.             else
  201.                 usage (1);
  202.             break;
  203.  
  204.         case 'm':        /* with -fl, do montage */
  205.             montage++;
  206.             break;
  207.  
  208.         case 'p':
  209.             if (!strncmp (*argv, "-pi1", 4))
  210.                 Pi1++;
  211.             else if (!strncmp (*argv, "-pi2", 4))
  212.                 Pi2++;
  213.             else
  214.                 usage (1);
  215.             break;
  216.  
  217.         case 'b':        /* batch mode (no questions)*/
  218.             Batch = 1;    /* NOT IMPLEMENTED!!! */
  219.             break;
  220.  
  221.         case 'N':        /* NTSC lum equation */
  222.             UseNTSC = 1;
  223.             break;
  224.  
  225.         case 'i':        /* inquire only */
  226.             Inquire++;
  227.             break;
  228.  
  229.         case 'v':        /* version/verbose output */
  230.             if (!strncmp (*argv, "-vers", 5))
  231.             {
  232.                 printf ("%s\n", version);
  233.                 exit (0);
  234.             }
  235.             Verbose++;
  236.             break;
  237.  
  238.         case 'h':        /* help */
  239.             if (!strncmp (*argv, "-help", 5))
  240.             {
  241.                 usage (0);
  242.             }
  243.             break;
  244.  
  245.         default:
  246.             usage (1);
  247.             break;
  248.         }
  249.     }
  250.  
  251.  
  252.  
  253.     /*
  254.      *   make sure we have at least one file...
  255.      */
  256.     if (argc < 1)
  257.         usage (1);
  258.  
  259.  
  260.  
  261.     /*
  262.      *   just show flicker files and exit...
  263.      */
  264.     if (ShowFl)
  265.     {
  266.         /*
  267.          *   align to page boundary. use Raster as our screen buf
  268.          */
  269.         scrn = (int *) (((long) Raster + 256L) & 0xFFFFFF00L);
  270.  
  271.  
  272.         if (montage)
  273.         {
  274.             /*
  275.              *   for either 2 320x400, 4 320x200 images or
  276.              *   6 200x200 images. first read them. note
  277.              *   changing ptr into screen buffers...
  278.              */
  279.             pscrn = scrn;
  280.             count = 0;
  281.             while (argc--)
  282.             {
  283.                 /*
  284.                  *   read a file
  285.                  */
  286.                 printf ("Reading file: %s\n", *argv);
  287.                 if (!read_fl (*argv, pscrn, &Width, &Height))
  288.                 {
  289.                     fprintf (stderr, "%s: read_fl failed for %s\n", myname, *argv);
  290.                     exit (1);
  291.                 }
  292.  
  293.  
  294.                 /*
  295.                  *   based on screen size of this image,
  296.                  *   change pointer to screen, get ready
  297.                  *   to read the next...
  298.                  */
  299.                 count++;
  300.                 argv++;
  301.                 if ((Width <= 320) && (Width > 200)
  302.                 && (Height <= 400) && (Height > 200))
  303.                 {
  304.                     /*
  305.                      *   2 320x400 images...
  306.                      */
  307.                     if (count == 1)
  308.                         pscrn = (int *) ((long) scrn + 40L);
  309.                     else
  310.                         break;
  311.                 }
  312.                 else if ((Width <= 320) && (Width > 200)
  313.                 && (Height <= 200))
  314.                 {
  315.                     /*
  316.                      *   4 320x200 images...
  317.                      */
  318.                     if (count == 1)
  319.                         pscrn = (int *) ((long) scrn + 40L);
  320.                     else if (count == 2)
  321.                         pscrn = (int *) ((long) scrn + 16000L);
  322.                     else if (count == 3)
  323.                         pscrn = (int *) ((long) scrn + 16040L);
  324.                     else
  325.                         break;
  326.                 }
  327.                 else if ((Width <= 200) && (Height <= 200))
  328.                 {
  329.                     /*
  330.                      *   6 200x200 images...
  331.                      */
  332.                     if (count == 1)
  333.                         pscrn = (int *) ((long) scrn + 25L);
  334.                     else if (count == 2)
  335.                         pscrn = (int *) ((long) scrn + 50L);
  336.                     else if (count == 3)
  337.                         pscrn = (int *) ((long) scrn + 16000L);
  338.                     else if (count == 4)
  339.                         pscrn = (int *) ((long) scrn + 16025L);
  340.                     else if (count == 5)
  341.                         pscrn = (int *) ((long) scrn + 16050L);
  342.                     else
  343.                         break;
  344.                 }
  345.                 else
  346.                     /*
  347.                      *   just display this one
  348.                      */
  349.                     break;
  350.             }
  351.  
  352.  
  353.             /*
  354.              *   show them all...
  355.              */
  356.             showfl (scrn);
  357.         }
  358.         else
  359.         {
  360.             /*
  361.              *   loop on files
  362.              */
  363.             while (argc--)
  364.             {
  365.                 /*
  366.                  *   read file. if ok, display...
  367.                  */
  368.                 printf ("Reading file: %s\n", *argv);
  369.                 if (read_fl (*argv, scrn, &Width, &Height))
  370.                     showfl (scrn);
  371.                 else
  372.                 {
  373.                     fprintf (stderr, "%s: read_fl failed for %s\n", myname, *argv);
  374.                     exit (1);
  375.                 }
  376.  
  377.  
  378.                 /*
  379.                  *   clear screen buffer for next image if there
  380.                  *   is one...
  381.                  */
  382.                 if (argc)
  383.                 {
  384.                     pscrn = scrn;
  385.                     for (ii = 0L; ii < SCRNSPACE; ii++)
  386.                         *pscrn++ = 0;
  387.                     argv++;
  388.                 }
  389.             }
  390.         }
  391.  
  392.         exit (0);
  393.     }
  394.  
  395.  
  396.  
  397.     /*
  398.      *   instructions (col, row)...
  399.      */
  400.     do_time (0);
  401.     if (!Inquire)
  402.     {
  403.         /*
  404.          *   initialize things (clear screen, turn off cursor, init
  405.          *   timing)
  406.          */
  407.         title (Batch);
  408.     }
  409.  
  410.  
  411.  
  412.     /*
  413.      *   loop on remaining files...
  414.      */
  415.     while (argc--)
  416.     {
  417.         /*
  418.          *   fresh screen...
  419.          */
  420.         if (!Inquire)
  421.             clr_screen ();
  422.  
  423.  
  424.         /*
  425.          *   get file to open
  426.          */
  427.         fname = *argv++;
  428.  
  429.  
  430.         /*
  431.          *   read image
  432.          */
  433.         if (Pi1)
  434.         {
  435.             /*
  436.              *   read PI1
  437.              */
  438.             do_time (1);
  439.             if (Verbose)
  440.                 ret = ReadPI1 (fname, Raster, ColMap, VERBOSE);
  441.             else if (Inquire)
  442.                 ret = ReadPI1 (fname, Raster, ColMap, INQUIRE);
  443.             else
  444.                 ret = ReadPI1 (fname, Raster, ColMap, NORMAL);
  445.             elapsed = do_time (2);
  446.  
  447.             Width  = 320;
  448.             Height = 200;
  449.         }
  450.         else if (Pi2)
  451.         {
  452.             /*
  453.              *   read PI2. Will need to be resized after this
  454.              *   for correct aspect ration (either shrink horiz
  455.              *   or enlarge vert, but let user decide...)
  456.              */
  457. #if 0
  458.             fprintf (stderr, "%s: can't do PI2 files (yet)\n", myname);
  459.             goto next;
  460. #endif
  461.             printf ("\nAfter PI2 is read, you will have to shrink horiz or expand vert...\n\n");
  462.             do_time (1);
  463.             if (Verbose)
  464.                 ret = ReadPI2 (fname, Raster, ColMap, VERBOSE);
  465.             else if (Inquire)
  466.                 ret = ReadPI2 (fname, Raster, ColMap, INQUIRE);
  467.             else
  468.                 ret = ReadPI2 (fname, Raster, ColMap, NORMAL);
  469.             elapsed = do_time (2);
  470.  
  471.             Width  = 640;
  472.             Height = 200;
  473.         }
  474.         else
  475.         {
  476.             /*
  477.              *   read GIF (this assumes only 1 image per file, a
  478.              *   reasonable assumption)...
  479.              */
  480.             do_time (1);
  481.             if (Verbose)
  482.                 ret = ReadGIF (fname, CodedGIF, Raster, &ScrnInf, &Id, ColMap, VERBOSE);
  483.             else if (Inquire)
  484.                 ret = ReadGIF (fname, CodedGIF, Raster, &ScrnInf, &Id, ColMap, INQUIRE);
  485.             else
  486.                 ret = ReadGIF (fname, CodedGIF, Raster, &ScrnInf, &Id, ColMap, NORMAL);
  487.             elapsed = do_time (2);
  488.  
  489.             Width  = Id.i_dx;
  490.             Height = Id.i_dy;
  491.         }
  492.  
  493.  
  494.         /*
  495.          *   draw if read was ok, else error and go to next file
  496.          */
  497.         switch (ret)
  498.         {
  499.         case EGIFOK:
  500.             printf ("\nElapsed time: %4ld sec\n", elapsed);
  501.  
  502.             if (!Inquire)
  503.                 draw_image (fname);
  504.             break;
  505.  
  506.         case EGIFFILE:
  507.             fprintf (stderr, "%s: could not open %s\n", myname, fname);
  508.             goto next;
  509.  
  510.         case EGIFMAGIC:
  511.             if (Pi1)
  512.                 fprintf (stderr, "%s: %s not a PI1 file\n", myname, fname);
  513.             else
  514.                 fprintf (stderr, "%s: %s not a GIF87a file\n", myname, fname);
  515.             goto next;
  516.  
  517.         case EGIFSDESC:
  518.             fprintf (stderr,
  519.                 "%s: file %s data format error in screen descriptor\n",
  520.                 myname, fname);
  521.             goto next;
  522.  
  523.         case EGIFEOF:
  524.             fprintf (stderr, "%s: unexpected EOF\n", myname);
  525.             goto next;
  526.  
  527.         case EGIFIDBAD:
  528.             fprintf (stderr, "%s: bad image ID\n", myname);
  529.             goto next;
  530.  
  531.         case EGIFBIG:
  532.             fprintf (stderr, "this GIF too large for memory\n\n");
  533.             goto next;
  534.  
  535.         case EGIFRAST:
  536.             fprintf (stderr, "%s: error reading raster image\n", myname);
  537.             goto next;
  538.         }
  539.  
  540. next:
  541.     }
  542.  
  543.  
  544.     /*
  545.      *   clean up and exit
  546.      */
  547.     cursor (1);
  548.  
  549.     exit (0);
  550. }
  551.  
  552.  
  553.  
  554.  
  555. /*------------------------------*/
  556. /*    usage            */
  557. /*------------------------------*/
  558. usage (excode)
  559. int    excode;
  560. {
  561.  
  562.     fprintf (stderr, "%s -fl [-m] file.fl ...\n", myname);
  563.     fprintf (stderr, "-m       montage of flicker files\n");
  564.     fprintf (stderr, "file.fl  a .fl flicker file\n");
  565.  
  566.     fprintf (stderr, "\nor:\n\n");
  567.  
  568.     fprintf (stderr, "%s [-i] [-v] [-N] [-pi1] [-pi2] file ...\n", myname);
  569.     fprintf (stderr, "-i       inquire about image only\n");
  570.     fprintf (stderr, "-v       verbose\n");
  571. /*    fprintf (stderr, "-b       batch mode (no questions asked)\n");*/
  572.     fprintf (stderr, "-N       use NTSC equation for luminescence\n");
  573.     fprintf (stderr, "-pi1     read Degas .pi1 file instead \n");
  574.     fprintf (stderr, "-pi2     read Degas .pi2 file instead \n");
  575.     fprintf (stderr, "file     a .gif (or .pi1 or .pi2) file\n");
  576.     fprintf (stderr, "\n");
  577.     fprintf (stderr, "If more than one file, all share command switch settings.\n");
  578.     fprintf (stderr, "Note that flicker file format is still subject to change.\n");
  579.     fprintf (stderr, "All flicker files created now, however, will be ok for the future.\n");
  580.  
  581.     cursor (1);
  582.     exit (excode);
  583. }
  584.  
  585.  
  586.  
  587.  
  588. /*------------------------------*/
  589. /*    draw_image        */
  590. /*------------------------------*/
  591. int draw_image (fname)
  592. char   *fname;
  593. {
  594.     int        i;
  595.     int        key;
  596.     int        orig;
  597.     int        ret;
  598.     char        buf[256];
  599.     long        ii;
  600.     int        lo, hi;
  601.     int        brite;
  602.     int        thresh;
  603.     long        cthresh;
  604.     int        conv;
  605.     int        convkern[20];
  606.     int        x1, y1, x2, y2;
  607.     int        xstart, ystart;
  608.     int        angle;
  609.     int        opt;
  610.     char           *flname;
  611.     long        elapsed;    /* elapsed seconds */
  612.  
  613.  
  614.  
  615.     /*
  616.      *   convert to grayscale
  617.      */
  618.     printf ("\nConvert to grayscale\n");
  619.     do_time (1);
  620.     cmaptoint (Raster, Width, Height, ColMap, UseNTSC);
  621.     elapsed = do_time (2);
  622.     printf ("\nElapsed time: %4ld sec\n", elapsed);
  623.  
  624.  
  625.     /*
  626.      *   copy image to transform array
  627.      */
  628.     do_time (1);
  629.     printf ("\nCopy to transform array\n");
  630.     copyrast (Raster, Width, Height, TransRast);
  631.     elapsed = do_time (2);
  632.     printf ("\nElapsed time: %4ld sec\n", elapsed);
  633.  
  634.  
  635.     /*
  636.      *   display flicker image. flicker returns after 2 keys. flicker
  637.      *   returns ptr to the 3 screens, page aligned, as (int *). this
  638.      *   address should not change so we only need assign PScreens once.
  639.      */
  640.     clr_screen ();
  641.     PScreens = flicker (Raster, Width, Height, Beta, Noise, 1);
  642.  
  643.  
  644.     /*
  645.      *   look for commands. redisplay image as required from TransRast.
  646.      *   orig set 0 so successive transforms will be on new image. 'o'
  647.      *   option toggles this so each transform will be done on orig image.
  648.      */
  649.     orig      = 0;
  650.     NewWidth  = Width;
  651.     NewHeight = Height;
  652.     while (1)
  653.     {
  654.         /*
  655.          *   get a command. they can be:
  656.          *
  657.          *   commands
  658.          *    ?    help
  659.          *    q    quit (next image)
  660.          *    ESC    exit program now
  661.          *    space   draw image
  662.          *    hi    histogram
  663.          *    o    original image (otherwise transform new)
  664.          *    f    file operations
  665.          *    cp    copy new <-> orig
  666.          *   options
  667.          *    n    noise
  668.          *    g    Laplace filter (need beta)
  669.          *   frame processes
  670.          *    e    enlarge
  671.          *    s    shrink
  672.          *    cu    cut
  673.          *    r    rotate
  674.          *    mi    mirror
  675.          *   point processes
  676.          *    he    histogram equalization
  677.          *    i    inverse (negation)
  678.          *    l    log scaling
  679.          *    t    threshold (black/white)
  680.          *    co    contrast expansion (need new range)
  681.          *    br    brighten
  682.          *   area processes
  683.          *    bl    blur (3x3)
  684.          *    me    median filter (3x3)
  685.          *    v    convolution (3x3)
  686.          */
  687.         clr_cmd ();        mv_cursor (0, 24);
  688.         /*printf (" Command, new(?,q,ESC,SPC,hi,o,f,cp,n,g,e,s,cu,r,mi,he,i,l,t,co,br,bl,me,v): ");*/
  689.         if (orig)
  690.             printf (" Command for original image (use ? for help): ");
  691.         else
  692.             printf (" Command for new image (use ? for help): ");
  693.         key = get_key ();
  694.         if ((key > 31) && (key < 128))
  695.             printf ("%c", (char) key);
  696.  
  697.         switch (key)
  698.         {
  699.         case '?':            /* help */
  700.             do_help ();
  701.             break;
  702.  
  703.         case 0x1b:            /* ESC, exit program */
  704.             clr_cmd ();
  705.             mv_cursor (0, 24);
  706.             printf (" Are you sure you want to exit? (y/n): ");
  707.             key = get_key ();
  708.             printf ("%c", (char) key);
  709.             if ((key == 'y') || (key == 'Y'))
  710.             {
  711.                 printf ("\n Program exit\n");
  712.                 cursor (1);
  713.                 exit (0);
  714.             }
  715.             break;
  716.  
  717.         case 'Q':            /* quit (next image) */
  718.         case 'q':
  719.             goto endloop;
  720.             break;
  721.  
  722.         case 'W':            /* what */
  723.         case 'w':
  724.             info (fname);
  725.             break;
  726.  
  727.         case 'F':            /* file operations */
  728.         case 'f':
  729.             /*
  730.              *   write a .fl file
  731.              */
  732.             clr_cmd ();
  733.             mv_cursor (0, 24);
  734.             printf (" Filename to write (*.FL): ");
  735.             get_string (83, buf);
  736.             flname = (char *) buf;
  737.  
  738.             clr_cmd ();
  739.             mv_cursor (0, 24);
  740.             printf (" Write file %s now...", flname);
  741.             if (PScreens)
  742.             {
  743.                 if (orig)
  744.                 {
  745.                     if (write_fl (flname, PScreens, Width, Height))
  746.                     {
  747.                         mv_cursor (0, 24);
  748.                         printf (" Wrote .FL file %s (%dx%d). Any key...", flname, Width, Height);
  749.                         wait_key ();
  750.                     }
  751.                     else
  752.                     {
  753.                         mv_cursor (0, 24);
  754.                         printf (" Error writing .FL file %s. Any key...", flname);
  755.                         wait_key ();
  756.                     }
  757.                 }
  758.                 else
  759.                 {
  760.                     if (write_fl (flname, PScreens, NewWidth, NewHeight))
  761.                     {
  762.                         mv_cursor (0, 24);
  763.                         printf (" Wrote .FL file %s (%dx%d). Any key...", flname, NewWidth, NewHeight);
  764.                         wait_key ();
  765.                     }
  766.                     else
  767.                     {
  768.                         mv_cursor (0, 24);
  769.                         printf (" Error writing .FL file %s. Any key...", flname);
  770.                         wait_key ();
  771.                     }
  772.                 }
  773.             }
  774.             else
  775.             {
  776.                 mv_cursor (0, 24);
  777.                 printf (" PScreens NULL! Any key...");
  778.                 wait_key ();
  779.             }
  780.             break;
  781.  
  782.         case 'H':            /* histogram */
  783.         case 'h':
  784.             key = get_key ();
  785.             printf ("%c", (char) key);
  786.             switch (key)
  787.             {
  788.             case 'I':        /* histogram */
  789.             case 'i':
  790.                 clr_cmd ();
  791.                 mv_cursor (0, 24);  printf (" Generating histogram...");
  792.                 if (orig)
  793.                 {
  794.                     if (do_hist (Raster, Width, Height, Hist))
  795.                     {
  796.                         clr_screen ();
  797.                         draw_hist (Hist);
  798.                     }
  799.                     else
  800.                     {
  801.                         clr_cmd ();
  802.                         mv_cursor (0, 24);  printf (" Histogram failed. Enter any key... ");
  803.                         wait_key ();
  804.                     }
  805.                 }
  806.                 else
  807.                 {
  808.                     if (do_hist (TransRast, NewWidth, NewHeight, Hist))
  809.                     {
  810.                         clr_screen ();
  811.                         draw_hist (Hist);
  812.                     }
  813.                     else
  814.                     {
  815.                         clr_cmd ();
  816.                         mv_cursor (0, 24);  printf (" Histogram failed. Enter any key... ");
  817.                         wait_key ();
  818.                     }
  819.                 }
  820.                 break;
  821.  
  822.             case 'E':        /* hist equal */
  823.             case 'e':
  824.                 clr_cmd ();
  825.                 mv_cursor (0, 24);  printf (" Histogram equalization now...");
  826.                 if (orig)
  827.                 {
  828.                     if (histeq (Raster, Width, Height, Hist, TransRast))
  829.                     {
  830.                         clr_screen ();
  831.                         flicker (TransRast, Width, Height, Beta, Noise, 1);
  832.                     }
  833.                     else
  834.                     {
  835.                         clr_cmd ();
  836.                         mv_cursor (0, 24);  printf (" Histogram equalization failed. Enter any key... ");
  837.                         wait_key ();
  838.                     }
  839.                 }
  840.                 else
  841.                 {
  842.                     if (histeq (TransRast, NewWidth, NewHeight, Hist, TransRast))
  843.                     {
  844.                         clr_screen ();
  845.                         flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  846.                     }
  847.                     else
  848.                     {
  849.                         clr_cmd ();
  850.                         mv_cursor (0, 24);  printf (" Histogram equalization failed. Enter any key... ");
  851.                         wait_key ();
  852.                     }
  853.                 }
  854.                 break;
  855.  
  856.             default:
  857.                 clr_cmd ();
  858.                 mv_cursor (0, 24);
  859.                 printf (" Unknown command. Type ? for help. Enter any key... ");
  860.                 wait_key ();
  861.                 break;
  862.             }
  863.             break;
  864.  
  865.         case 'Z':            /* zoom (2x) */
  866.         case 'z':
  867.             clr_screen ();
  868.             if (orig)
  869.             {
  870.                 clr_screen ();
  871.                 flicker (Raster, Width, Height, Beta, Noise, 0);
  872.                 grid (0, 0, Width, Height, 20);
  873.             }
  874.             else
  875.             {
  876.                 clr_screen ();
  877.                 flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 0);
  878.                 grid (0, 0, NewWidth, NewHeight, 20);
  879.             }
  880.  
  881.             /*
  882.              *   get zoom rectangle. it is currently ALWAYS
  883.              *   half the width and height of the current image.
  884.              *   the resulting zoom will ALWAYS be the same
  885.              *   size as the original image (well ALMOST, since
  886.              *   odd dims rounded down first)...
  887.              */
  888.             if (orig)
  889.             {
  890.                 xstart = Width/4;
  891.                 if ((xstart % 20) == 0)
  892.                     xstart -= 2;
  893.                 ystart = Height/4;
  894.                 if ((ystart % 20) == 0)
  895.                     ystart -= 2;
  896.  
  897. ret = get_xypos (VH_COORD, 1, 0, 0, Width, Height, Width/2, Height/2, xstart, ystart, &x1, &y1);
  898.  
  899.                 if (ret == 0)
  900.                 {
  901.                     clr_cmd ();
  902.                     mv_cursor (0, 24);
  903.                     printf (" Canceled or failed. Any key... ");
  904.                     wait_key ();
  905.                     break;
  906.                 }
  907.             }
  908.             else
  909.             {
  910.                 xstart = NewWidth/4;
  911.                 if ((xstart % 20) == 0)
  912.                     xstart -= 2;
  913.                     ystart = NewHeight/4;
  914.                     if ((ystart % 20) == 0)
  915.                         ystart -= 2;
  916.  
  917. ret = get_xypos (VH_COORD, 1, 0, 0, NewWidth, NewHeight, NewWidth/2, NewHeight/2, xstart, ystart, &x1, &y1);
  918.  
  919.                 if (ret == 0)
  920.                 {
  921.                     clr_cmd ();
  922.                     mv_cursor (0, 24);
  923.                     printf (" Canceled or failed. Any key... ");
  924.                     wait_key ();
  925.                     break;
  926.                 }
  927.             }
  928.  
  929.             clr_cmd ();
  930.             mv_cursor (0, 24);
  931.             printf (" Zooming image now (%d,%d)...", x1,y1);
  932.  
  933.             if (orig)
  934.                 ret = zoom (Raster, Width, Height, x1, y1, TransRast);
  935.             else
  936.                 ret = zoom (TransRast, NewWidth, NewHeight, x1, y1, TransRast);
  937.  
  938.             /*
  939.              *   if zoom was successful, show the new image.
  940.              */
  941.             if (ret)
  942.             {
  943.                 if (orig)
  944.                 {
  945.                     /* order of * and / IS important! */
  946.                     NewWidth  = 2 * (Width / 2);
  947.                     NewHeight = 2 * (Height / 2);
  948.                 }
  949.                 else
  950.                 {
  951.                     NewWidth  = 2 * (NewWidth / 2);
  952.                     NewHeight = 2 * (NewHeight / 2);
  953.                 }
  954.  
  955.                 clr_screen ();
  956.                 flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  957.             }
  958.             else
  959.             {
  960.                 clr_cmd ();
  961.                 mv_cursor (0, 24);  printf (" Zoom failed. Enter any key... ");
  962.                 wait_key ();
  963.             }
  964.  
  965.             break;
  966.  
  967.         case 'E':            /* enlarge (2x) */
  968.         case 'e':
  969. e_again:
  970.             clr_cmd ();
  971.             mv_cursor (0, 24);
  972.             printf (" Enlarge dimension (0=both,1=horizontal,2=vertical): ");
  973.             get_string (32, buf);
  974.             opt = atoi (buf);
  975.             if ((opt < 0) || (opt > 2))
  976.                 goto e_again;
  977.  
  978.             clr_cmd ();
  979.             mv_cursor (0, 24);  printf (" Enlarging image now...");
  980.             if (orig)
  981.                 ret = larger (Raster, Width, Height, opt, TransRast);
  982.             else
  983.                 ret = larger (TransRast, NewWidth, NewHeight, opt, TransRast);
  984.  
  985.             if (ret)
  986.             {
  987.                 if (orig)
  988.                 {
  989.                     switch (opt)
  990.                     {
  991.                     case 0:            /* both */
  992.                         NewWidth  = 2 * Width;
  993.                         NewHeight = 2 * Height;
  994.                         break;
  995.                     case 1:            /* horiz */
  996.                         NewWidth  = 2 * Width;
  997.                         NewHeight = Height;
  998.                         break;
  999.                     case 2:            /* vert */
  1000.                         NewWidth  = Width;
  1001.                         NewHeight = 2 * Height;
  1002.                         break;
  1003.                     }
  1004.                 }
  1005.                 else
  1006.                 {
  1007.                     switch (opt)
  1008.                     {
  1009.                     case 0:
  1010.                         NewWidth  = 2 * NewWidth;
  1011.                         NewHeight = 2 * NewHeight;
  1012.                         break;
  1013.                     case 1:
  1014.                         NewWidth  = 2 * NewWidth;
  1015.                         NewHeight = NewHeight;
  1016.                         break;
  1017.                     case 2:
  1018.                         NewWidth  = NewWidth;
  1019.                         NewHeight = 2 * NewHeight;
  1020.                         break;
  1021.                     }
  1022.                 }
  1023.  
  1024.                 clr_screen ();
  1025.                 flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1026.             }
  1027.             else
  1028.             {
  1029.                 clr_cmd ();
  1030.                 mv_cursor (0, 24);  printf (" Enlarged image too large. Enter any key... ");
  1031.                 wait_key ();
  1032.             }
  1033.             break;
  1034.  
  1035.         case 'S':            /* shrink (.5x) */
  1036.         case 's':
  1037. s_again:
  1038.             clr_cmd ();
  1039.             mv_cursor (0, 24);
  1040.             printf (" Shrink dimension (0=both,1=horizontal,2=vertical): ");
  1041.             get_string (32, buf);
  1042.             opt = atoi (buf);
  1043.             if ((opt < 0) || (opt > 2))
  1044.                 goto s_again;
  1045.  
  1046.             clr_cmd ();
  1047.             mv_cursor (0, 24);  printf (" Reducing image now...");
  1048.             if (orig)
  1049.                 ret = smaller (Raster, Width, Height, opt, TransRast);
  1050.             else
  1051.                 ret = smaller (TransRast, NewWidth, NewHeight, opt, TransRast);
  1052.  
  1053.             if (ret)
  1054.             {
  1055.                 if (orig)
  1056.                 {
  1057.                     switch (opt)
  1058.                     {
  1059.                     case 0:            /* both */
  1060.                         NewWidth  = Width / 2;
  1061.                         NewHeight = Height / 2;
  1062.                         break;
  1063.                     case 1:            /* horiz */
  1064.                         NewWidth  = Width / 2;
  1065.                         NewHeight = Height;
  1066.                         break;
  1067.                     case 2:            /* vert */
  1068.                         NewWidth  = Width;
  1069.                         NewHeight = Height / 2;
  1070.                         break;
  1071.                     }
  1072.                 }
  1073.                 else
  1074.                 {
  1075.                     switch (opt)
  1076.                     {
  1077.                     case 0:
  1078.                         NewWidth  = NewWidth / 2;
  1079.                         NewHeight = NewHeight / 2;
  1080.                         break;
  1081.                     case 1:
  1082.                         NewWidth  = NewWidth / 2;
  1083.                         NewHeight = NewHeight;
  1084.                         break;
  1085.                     case 2:
  1086.                         NewWidth  = NewWidth;
  1087.                         NewHeight = NewHeight / 2;
  1088.                         break;
  1089.                     }
  1090.                 }
  1091.  
  1092.                 clr_screen ();
  1093.                 flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1094.             }
  1095.             else
  1096.             {
  1097.                 clr_cmd ();
  1098.                 mv_cursor (0, 24);  printf (" Reduced image too small. Enter any key... ");
  1099.                 wait_key ();
  1100.             }
  1101.             break;
  1102.  
  1103.         case 'R':            /* rotate */
  1104.         case 'r':
  1105.             if (!orig)
  1106.             {
  1107.                 clr_cmd ();
  1108.                 mv_cursor (0, 24);
  1109.                 printf (" Can only rotate original image Any new image will be lost. Proceed (y/n)? ");
  1110.                 key = get_key ();
  1111.                 printf ("%c", (char) key);
  1112.                 if ((key != 'y') && (key != 'Y'))
  1113.                     break;
  1114.             }
  1115.  
  1116.             clr_cmd ();
  1117.             mv_cursor (0, 24);
  1118.             printf (" Enter angle (90=CCW,-90=CW,180): ");
  1119.             get_string (32, buf);
  1120.             angle = atoi (buf);
  1121.  
  1122.             if ((angle != 90) && (angle != -90)
  1123.             &&  (angle != 180) && (angle != -180))
  1124.             {
  1125.                 clr_cmd ();
  1126.                 mv_cursor (0, 24);
  1127.                 printf (" Sorry. Bad or unsupported angle. Enter any key... ");
  1128.                 wait_key ();
  1129.                 break;
  1130.             }
  1131.  
  1132.             clr_cmd ();
  1133.             mv_cursor (0, 24);
  1134.             printf (" Forcing orig mode. After rotate, force new mode. Rotate image now...");
  1135.             if (rotate (Raster, Width, Height, angle, TransRast))
  1136.             {
  1137.                 if ((angle == 90) || (angle == -90))
  1138.                 {
  1139.                     NewWidth  = Height;
  1140.                     NewHeight = Width;
  1141.                 }
  1142.                 else if ((angle == 180) || (angle == -180))
  1143.                 {
  1144.                     NewWidth  = Width;
  1145.                     NewHeight = Height;
  1146.                 }
  1147.                 else
  1148.                 {
  1149.                     clr_cmd ();
  1150.                     mv_cursor (0, 24);
  1151.                     printf (" Sorry. Bad or unsupported angle. Enter any key... ");
  1152.                     wait_key ();
  1153.                     break;
  1154.                 }
  1155.  
  1156.                 clr_cmd ();
  1157.                 mv_cursor (0, 24);
  1158.                 printf ("Copy to new to orig image...");
  1159.                 copyrast (TransRast, NewWidth, NewHeight, Raster);
  1160.                 Width  = NewWidth;
  1161.                 Height = NewHeight;
  1162.  
  1163.                 clr_screen ();
  1164.                 flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1165.  
  1166.                 orig = 0;
  1167.             }
  1168.             else
  1169.             {
  1170.                 clr_cmd ();
  1171.                 mv_cursor (0, 24);
  1172.                 printf (" Rotation failed. Could be bad angle. Mode unchanged. Enter any key... ");
  1173.                 wait_key ();
  1174.             }
  1175.             break;
  1176.  
  1177.         case 'T':            /* threshold */
  1178.         case 't':
  1179.             clr_cmd ();
  1180.             mv_cursor (0, 24);  printf (" Enter threshold (0 to 255): ");
  1181.             get_string (32, buf);
  1182.             thresh = atoi (buf);
  1183.  
  1184.             clr_cmd ();
  1185.             mv_cursor (0, 24);  printf (" Thresholding image now...");
  1186.             if (orig)
  1187.             {
  1188.                 if (threshold (Raster, Width, Height, thresh, TransRast))
  1189.                 {
  1190.                     clr_screen ();
  1191.                     flicker (TransRast, Width, Height, Beta, Noise, 1);
  1192.                 }
  1193.                 else
  1194.                 {
  1195.                     clr_cmd ();
  1196.                     mv_cursor (0, 24);  printf (" Threshold failed. Enter any key... ");
  1197.                     wait_key ();
  1198.                 }
  1199.             }
  1200.             else
  1201.             {
  1202.                 if (threshold (TransRast, NewWidth, NewHeight, thresh, TransRast))
  1203.                 {
  1204.                     clr_screen ();
  1205.                     flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1206.                 }
  1207.                 else
  1208.                 {
  1209.                     clr_cmd ();
  1210.                     mv_cursor (0, 24);  printf (" Threshold failed. Enter any key... ");
  1211.                     wait_key ();
  1212.                 }
  1213.             }
  1214.             break;
  1215.  
  1216.         case 'I':            /* inverse (negation) */
  1217.         case 'i':
  1218.             clr_cmd ();
  1219.             mv_cursor (0, 24);  printf (" Enter threshold (0 to 255): ");
  1220.             get_string (32, buf);
  1221.             thresh = atoi (buf);
  1222.  
  1223.             clr_cmd ();
  1224.             mv_cursor (0, 24);  printf (" Invert (negate) image now...");
  1225.             if (orig)
  1226.             {
  1227.                 if (invert (Raster, Width, Height, thresh, TransRast))
  1228.                 {
  1229.                     clr_screen ();
  1230.                     flicker (TransRast, Width, Height, Beta, Noise, 1);
  1231.                 }
  1232.                 else
  1233.                 {
  1234.                     clr_cmd ();
  1235.                     mv_cursor (0, 24);  printf (" Inversion failed. Enter any key... ");
  1236.                     wait_key ();
  1237.                 }
  1238.             }
  1239.             else
  1240.             {
  1241.                 if (invert (TransRast, NewWidth, NewHeight, thresh, TransRast))
  1242.                 {
  1243.                     clr_screen ();
  1244.                     flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1245.                 }
  1246.                 else
  1247.                 {
  1248.                     clr_cmd ();
  1249.                     mv_cursor (0, 24);  printf (" Inversion failed. Enter any key... ");
  1250.                     wait_key ();
  1251.                 }
  1252.             }
  1253.             break;
  1254.         
  1255.         case 'L':            /* log scaling */
  1256.         case 'l':
  1257.             clr_cmd ();
  1258.             mv_cursor (0, 24);  printf (" Log scaling image now...");
  1259.             if (orig)
  1260.             {
  1261.                 if (logscale (Raster, Width, Height, TransRast))
  1262.                 {
  1263.                     clr_screen ();
  1264.                     flicker (TransRast, Width, Height, Beta, Noise, 1);
  1265.                 }
  1266.                 else
  1267.                 {
  1268.                     clr_cmd ();
  1269.                     mv_cursor (0, 24);  printf (" Log scaling failed. Enter any key... ");
  1270.                     wait_key ();
  1271.                 }
  1272.             }
  1273.             else
  1274.             {
  1275.                 if (logscale (TransRast, NewWidth, NewHeight, TransRast))
  1276.                 {
  1277.                     clr_screen ();
  1278.                     flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1279.                 }
  1280.                 else
  1281.                 {
  1282.                     clr_cmd ();
  1283.                     mv_cursor (0, 24);  printf (" Log scaling failed. Enter any key... ");
  1284.                     wait_key ();
  1285.                 }
  1286.             }
  1287.             break;
  1288.  
  1289.         case 'C':            /* cut/contrast expansion */
  1290.         case 'c':
  1291.             key = get_key ();
  1292.             printf ("%c", (char) key);
  1293.             switch (key)
  1294.             {
  1295.             case 'P':        /* copy */
  1296.             case 'p':
  1297.                 clr_cmd ();
  1298.                 mv_cursor (0, 24);  printf ("Enter copy direction (0=orig->new, 1=new->orig): ");
  1299.                 get_string (32, buf);
  1300.                 opt = atoi (buf);
  1301.  
  1302.                 switch (opt)
  1303.                 {
  1304.                 case 0:            /* orig->new */
  1305.                     clr_cmd ();
  1306.                     mv_cursor (0, 24);
  1307.                     printf ("Copy to orig to new image...");
  1308.  
  1309.                     copyrast (Raster, Width, Height, TransRast);
  1310.  
  1311.                     NewWidth  = Width;
  1312.                     NewHeight = Height;
  1313.                     break;
  1314.                 case 1:            /* new->orig */
  1315.                     clr_cmd ();
  1316.                     mv_cursor (0, 24);
  1317.                     printf ("Copy to new to orig image...");
  1318.  
  1319.                     copyrast (TransRast, NewWidth, NewHeight, Raster);
  1320.  
  1321.                     Width  = NewWidth;
  1322.                     Height = NewHeight;
  1323.                     break;
  1324.                 default:
  1325.                     clr_cmd ();
  1326.                     mv_cursor (0, 24);  printf (" Copy failed. Enter any key... ");
  1327.                     wait_key ();
  1328.                     break;
  1329.                 }
  1330.  
  1331.                 break;
  1332.  
  1333.             case 'U':        /* cut */
  1334.             case 'u':
  1335.                 clr_screen ();
  1336.                 if (orig)
  1337.                 {
  1338.                     clr_screen ();
  1339.                     flicker (Raster, Width, Height, Beta, Noise, 0);
  1340.                     grid (0, 0, Width, Height, 20);
  1341.                 }
  1342.                 else
  1343.                 {
  1344.                     clr_screen ();
  1345.                     flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 0);
  1346.                     grid (0, 0, NewWidth, NewHeight, 20);
  1347.                 }
  1348.  
  1349. #if 0
  1350.                 clr_cmd ();
  1351.                 mv_cursor (0, 24);
  1352.                 printf (" Enter x1 (upper left coord, 0-%d): ",
  1353.                     (orig ? Width-1 : NewWidth-1));
  1354.                 get_string (32, buf);
  1355.                 x1 = atoi (buf);
  1356.  
  1357.                 clr_cmd ();
  1358.                 mv_cursor (0, 24);
  1359.                 printf (" Enter y1 (upper left coord, 0-%d): ",
  1360.                     (orig ? Height-1 : NewHeight-1));
  1361.                 get_string (32, buf);
  1362.                 y1 = atoi (buf);
  1363.  
  1364.                 clr_cmd ();
  1365.                 mv_cursor (0, 24);
  1366.                 printf (" Enter x2 (lower right coord, %d-%d): ",
  1367.                     x1+1,
  1368.                     (orig ? Width-1 : NewWidth-1));
  1369.                 get_string (32, buf);
  1370.                 x2 = atoi (buf);
  1371.  
  1372.                 clr_cmd ();
  1373.                 mv_cursor (0, 24);
  1374.                 printf (" Enter y2 (lower right coord, %d-%d): ",
  1375.                     y1+1,
  1376.                     (orig ? Height-1 : NewHeight-1));
  1377.                 get_string (32, buf);
  1378.                 y2 = atoi (buf);
  1379. #endif
  1380.                 if (orig)
  1381.                 {
  1382.                     xstart = Width/2;
  1383.                     if ((xstart % 20) == 0)
  1384.                         xstart -= 5;
  1385.                     ystart = Height/2;
  1386.                     if ((ystart % 20) == 0)
  1387.                         ystart -= 5;
  1388.  
  1389. ret = get_xypos (VH_COORD, 0, 0, 0, Width, Height, 0, 0, xstart, ystart, &x1, &y1);
  1390.  
  1391.                     if (ret == 0)
  1392.                     {
  1393.                         clr_cmd ();
  1394.                         mv_cursor (0, 24);
  1395.                         printf (" Canceled or failed. Any key... ");
  1396.                         wait_key ();
  1397.                         break;
  1398.                     }
  1399.  
  1400.                     xstart = x1+1+(Width-x1-1)/2;
  1401.                     if ((xstart % 20) == 0)
  1402.                         xstart += 1;
  1403.                     xstart = y1+1+(Height-y1-1)/2;
  1404.                     if ((ystart % 20) == 0)
  1405.                         ystart += 1;
  1406.  
  1407. ret = get_xypos (VH_COORD, 0, x1+1, y1+1, Width-x1-1, Height-y1-1, 0, 0, xstart, ystart, &x2, &y2);
  1408.  
  1409.                     if (ret == 0)
  1410.                     {
  1411.                         clr_cmd ();
  1412.                         mv_cursor (0, 24);
  1413.                         printf (" Canceled or failed. Any key... ");
  1414.                         wait_key ();
  1415.                         break;
  1416.                     }
  1417.                 }
  1418.                 else
  1419.                 {
  1420.                     xstart = NewWidth/2;
  1421.                     if ((xstart % 20) == 0)
  1422.                         xstart -= 5;
  1423.                     ystart = NewHeight/2;
  1424.                     if ((ystart % 20) == 0)
  1425.                         ystart -= 5;
  1426.  
  1427. ret = get_xypos (VH_COORD, 0, 0, 0, NewWidth, NewHeight, 0, 0, xstart, ystart, &x1, &y1);
  1428.  
  1429.                     if (ret == 0)
  1430.                     {
  1431.                         clr_cmd ();
  1432.                         mv_cursor (0, 24);
  1433.                         printf (" Canceled or failed. Any key... ");
  1434.                         wait_key ();
  1435.                         break;
  1436.                     }
  1437.  
  1438.                     xstart = x1+1+(NewWidth-x1-1)/2;
  1439.                     if ((xstart % 20) == 0)
  1440.                         xstart += 1;
  1441.                     xstart = y1+1+(NewHeight-y1-1)/2;
  1442.                     if ((ystart % 20) == 0)
  1443.                         ystart += 1;
  1444.  
  1445. ret = get_xypos (VH_COORD, 0, x1+1, y1+1, NewWidth-x1-1, NewHeight-y1-1, 0, 0, xstart, ystart, &x2, &y2);
  1446.  
  1447.                     if (ret == 0)
  1448.                     {
  1449.                         clr_cmd ();
  1450.                         mv_cursor (0, 24);
  1451.                         printf (" Canceled or failed. Any key... ");
  1452.                         wait_key ();
  1453.                         break;
  1454.                     }
  1455.                 }
  1456.  
  1457.  
  1458.  
  1459.  
  1460.                 clr_cmd ();
  1461.                 mv_cursor (0, 24);
  1462.                 printf (" Cutting image now ((%d,%d) to (%d,%d)...", x1,y1, x2,y2);
  1463.                 if (orig)
  1464.                     ret = cut (Raster, Width, Height, x1, y1, x2, y2, TransRast);
  1465.                 else
  1466.                     ret = cut (TransRast, NewWidth, NewHeight, x1, y1, x2, y2, TransRast);
  1467.  
  1468.                 if (ret)
  1469.                 {
  1470.                     NewWidth  = x2 - x1 + 1;
  1471.                     NewHeight = y2 - y1 + 1;
  1472.  
  1473.                     clr_screen ();
  1474.                     flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1475.                 }
  1476.                 else
  1477.                 {
  1478.                     clr_cmd ();
  1479.                     mv_cursor (0, 24);  printf (" Cut image failed. Enter any key... ");
  1480.                     wait_key ();
  1481.                 }
  1482.                 break;
  1483.  
  1484.             case 'O':        /* contrast expansion */
  1485.             case 'o':
  1486. #if 0
  1487.                 clr_cmd ();
  1488.                 mv_cursor (0, 24);  printf (" Enter lo range (0-255): ");
  1489.                 get_string (32, buf);
  1490.                 lo = atoi (buf);
  1491.  
  1492.                 clr_cmd ();
  1493.                 mv_cursor (0, 24);  printf (" lo=%d. Enter hi range (0-255, larger than lo): ", lo);
  1494.                 get_string (32, buf);
  1495.                 hi = atoi (buf);
  1496. #endif
  1497.                 clr_cmd ();
  1498.                 mv_cursor (0, 24);  printf (" Enter threshold (pixel count): ");
  1499.                 get_string (32, buf);
  1500.                 cthresh = atol (buf);
  1501.  
  1502.  
  1503.                 clr_cmd ();
  1504.                 mv_cursor (0, 24);  printf (" Contrast expanding image now...");
  1505.                 if (orig)
  1506.                 {
  1507.                     if (contrast (Raster, Width, Height, cthresh, Hist, TransRast))
  1508.                     {
  1509.                         clr_screen ();
  1510.                         flicker (TransRast, Width, Height, Beta, Noise, 1);
  1511.                     }
  1512.                     else
  1513.                     {
  1514.                         clr_cmd ();
  1515.                         mv_cursor (0, 24);  printf (" Contrast expansion failed. Enter any key... ");
  1516.                         wait_key ();
  1517.                     }
  1518.                 }
  1519.                 else
  1520.                 {
  1521.                     if (contrast (TransRast, NewWidth, NewHeight, cthresh, Hist, TransRast))
  1522.                     {
  1523.                         clr_screen ();
  1524.                         flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1525.                     }
  1526.                     else
  1527.                     {
  1528.                         clr_cmd ();
  1529.                         mv_cursor (0, 24);  printf (" Contrast expansion failed. Enter any key... ");
  1530.                         wait_key ();
  1531.                     }
  1532.                 }
  1533.                 break;
  1534.  
  1535.             default:
  1536.                 clr_cmd ();
  1537.                 mv_cursor (0, 24);
  1538.                 printf (" Unknown command. Type ? for help. Enter any key... ");
  1539.                 wait_key ();
  1540.                 break;
  1541.             }
  1542.             break;
  1543.  
  1544.         case 'B':            /* blur or brighten */
  1545.         case 'b':
  1546.             key = get_key ();
  1547.             printf ("%c", (char) key);
  1548.             switch (key)
  1549.             {
  1550.             case 'L':        /* blur */
  1551.             case 'l':
  1552.                 clr_cmd ();
  1553.                 mv_cursor (0, 24);  printf (" Blurring image now...");
  1554.                 if (orig)
  1555.                 {
  1556.                     if (blur (Raster, Width, Height, TransRast))
  1557.                     {
  1558.                         clr_screen ();
  1559.                         flicker (TransRast, Width, Height, Beta, Noise, 1);
  1560.                     }
  1561.                     else
  1562.                     {
  1563.                         clr_cmd ();
  1564.                         mv_cursor (0, 24);  printf (" Blurring failed. Enter any key... ");
  1565.                         wait_key ();
  1566.                     }
  1567.                 }
  1568.                 else
  1569.                 {
  1570.                     if (blur (TransRast, NewWidth, NewHeight, TransRast))
  1571.                     {
  1572.                         clr_screen ();
  1573.                         flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1574.                     }
  1575.                     else
  1576.                     {
  1577.                         clr_cmd ();
  1578.                         mv_cursor (0, 24);  printf (" Blurring failed. Enter any key... ");
  1579.                         wait_key ();
  1580.                     }
  1581.                 }
  1582.                 break;
  1583.  
  1584.             case 'R':        /* brighten */
  1585.             case 'r':
  1586.                 clr_cmd ();
  1587.                 mv_cursor (0, 24);  printf (" Enter brightening value (-255 to 255): ");
  1588.                 get_string (32, buf);
  1589.                 brite = atoi (buf);
  1590.  
  1591.                 clr_cmd ();
  1592.                 mv_cursor (0, 24);  printf (" Brightening image now...");
  1593.                 if (orig)
  1594.                 {
  1595.                     if (brighten (Raster, Width, Height, brite, TransRast))
  1596.                     {
  1597.                         clr_screen ();
  1598.                         flicker (TransRast, Width, Height, Beta, Noise, 1);
  1599.                     }
  1600.                     else
  1601.                     {
  1602.                         clr_cmd ();
  1603.                         mv_cursor (0, 24);  printf (" Brightening failed. Enter any key... ");
  1604.                         wait_key ();
  1605.                     }
  1606.                 }
  1607.                 else
  1608.                 {
  1609.                     if (brighten (TransRast, NewWidth, NewHeight, brite, TransRast))
  1610.                     {
  1611.                         clr_screen ();
  1612.                         flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1613.                     }
  1614.                     else
  1615.                     {
  1616.                         clr_cmd ();
  1617.                         mv_cursor (0, 24);  printf (" Brightening failed. Enter any key... ");
  1618.                         wait_key ();
  1619.                     }
  1620.                 }
  1621.                 break;
  1622.  
  1623.             default:
  1624.                 clr_cmd ();
  1625.                 mv_cursor (0, 24);
  1626.                 printf (" Unknown command. Type ? for help. Enter any key... ");
  1627.                 wait_key ();
  1628.                 break;
  1629.             }
  1630.             break;
  1631.  
  1632.         case 'M':            /* mirror/median filter */
  1633.         case 'm':
  1634.             key = get_key ();
  1635.             printf ("%c", (char) key);
  1636.             switch (key)
  1637.             {
  1638.             case 'I':        /* mirror */
  1639.             case 'i':
  1640.                 clr_cmd ();
  1641.                 mv_cursor (0, 24);  printf (" Enter mirror direction (0=vertical, 1=horizontal): ");
  1642.                 get_string (32, buf);
  1643.                 opt = atoi (buf);
  1644.  
  1645.                 clr_cmd ();
  1646.                 mv_cursor (0, 24);  printf (" Mirror image now...");
  1647.                 if (orig)
  1648.                 {
  1649.                     if (mirror (Raster, Width, Height, opt, TransRast))
  1650.                     {
  1651.                         clr_screen ();
  1652.                         flicker (TransRast, Width, Height, Beta, Noise, 1);
  1653.                     }
  1654.                     else
  1655.                     {
  1656.                         clr_cmd ();
  1657.                         mv_cursor (0, 24);  printf (" Mirror failed. Enter any key... ");
  1658.                         wait_key ();
  1659.                     }
  1660.                 }
  1661.                 else
  1662.                 {
  1663.                     if (mirror (TransRast, NewWidth, NewHeight, opt, TransRast))
  1664.                     {
  1665.                         clr_screen ();
  1666.                         flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1667.                     }
  1668.                     else
  1669.                     {
  1670.                         clr_cmd ();
  1671.                         mv_cursor (0, 24);  printf (" Mirror failed. Enter any key... ");
  1672.                         wait_key ();
  1673.                     }
  1674.                 }
  1675.                 break;
  1676.  
  1677.             case 'E':
  1678.             case 'e':        /* median filter */
  1679.                 clr_cmd ();
  1680.                 mv_cursor (0, 24);  printf (" Median filter image now...");
  1681.                 if (orig)
  1682.                 {
  1683.                     if (median (Raster, Width, Height, TransRast))
  1684.                     {
  1685.                         clr_screen ();
  1686.                         flicker (TransRast, Width, Height, Beta, Noise, 1);
  1687.                     }
  1688.                     else
  1689.                     {
  1690.                         clr_cmd ();
  1691.                         mv_cursor (0, 24);  printf (" Median filter failed. Enter any key... ");
  1692.                         wait_key ();
  1693.                     }
  1694.                 }
  1695.                 else
  1696.                 {
  1697.                     if (median (TransRast, NewWidth, NewHeight, TransRast))
  1698.                     {
  1699.                         clr_screen ();
  1700.                         flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1701.                     }
  1702.                     else
  1703.                     {
  1704.                         clr_cmd ();
  1705.                         mv_cursor (0, 24);  printf (" Median filter failed. Enter any key... ");
  1706.                         wait_key ();
  1707.                     }
  1708.                 }
  1709.                 break;
  1710.  
  1711.             default:
  1712.                 clr_cmd ();
  1713.                 mv_cursor (0, 24);
  1714.                 printf (" Unknown command. Type ? for help. Enter any key... ");
  1715.                 wait_key ();
  1716.                 break;
  1717.             }
  1718.             break;
  1719.  
  1720.         case 'N':            /* add noise */
  1721.         case 'n':
  1722.             clr_cmd ();
  1723.             mv_cursor (0, 24);  printf (" Enter noise percentage (0-100): ");
  1724.             get_string (32, buf);
  1725.             Noise = atoi (buf);
  1726.             break;
  1727.  
  1728.         case 'G':            /* Laplace filter */
  1729.         case 'g':
  1730.             clr_cmd ();
  1731.             mv_cursor (0, 24);  printf (" Enter beta (0,1,2,3,4,...): ");
  1732.             get_string (32, buf);
  1733.             Beta = atoi (buf);
  1734.             break;
  1735.  
  1736.         case 'V':            /* convolutions */
  1737.         case 'v':
  1738.             conv_menu (1);
  1739.  
  1740.              clr_cmd ();
  1741.             mv_cursor (0, 24);  printf (" Enter your choice: ");
  1742.             get_string (32, buf);
  1743.             conv = atoi (buf);
  1744.  
  1745.             if (conv == USER_KERN)
  1746.             {
  1747.                 conv_menu (2);
  1748.  
  1749.                 for (i = 0; i < 9; i++)
  1750.                 {
  1751.                      clr_cmd ();
  1752.                     mv_cursor (0, 24);
  1753.                     printf (" Enter k%d (neg or pos integer): ", i);
  1754.                     get_string (32, buf);
  1755.                     convkern[i] = atoi (buf);
  1756.                 }
  1757.  
  1758.                  clr_cmd ();
  1759.                 mv_cursor (0, 24);
  1760.                 printf (" Scaling (if multiplier->1, divisor->-1, no scaling-> 0): ");
  1761.                 get_string (32, buf);
  1762.                 convkern[9] = atoi (buf);
  1763.                 if (convkern[9] > 0)
  1764.                 {
  1765.                      clr_cmd ();
  1766.                     mv_cursor (0, 24);
  1767.                     printf (" Multiplier (neg or pos integer): ");
  1768.                     get_string (32, buf);
  1769.                     convkern[10] = atoi (buf);
  1770.                 }
  1771.                 else if (convkern[9] < 0)
  1772.                 {
  1773. v_again:
  1774.                      clr_cmd ();
  1775.                     mv_cursor (0, 24);
  1776.                     printf (" Divisor (neg or pos integer, NOT 0!!!): ");
  1777.                     get_string (32, buf);
  1778.                     convkern[10] = atoi (buf);
  1779.                     if (convkern[10] == 0)
  1780.                         goto v_again;
  1781.                 }
  1782.                 else
  1783.                     convkern[10] = 1;
  1784.             }
  1785.  
  1786.             clr_cmd ();
  1787.             mv_cursor (0, 24);  printf (" Convolve image now...");
  1788.             if (orig)
  1789.             {
  1790.                 if (convolve (Raster, Width, Height, conv, convkern, TransRast))
  1791.                 {
  1792.                     clr_screen ();
  1793.                     flicker (TransRast, Width, Height, Beta, Noise, 1);
  1794.                 }
  1795.                 else
  1796.                 {
  1797.                     clr_cmd ();
  1798.                     mv_cursor (0, 24);  printf (" Convolution failed. Enter any key... ");
  1799.                     wait_key ();
  1800.                 }
  1801.             }
  1802.             else
  1803.             {
  1804.                 if (convolve (TransRast, NewWidth, NewHeight, conv, convkern, TransRast))
  1805.                 {
  1806.                     clr_screen ();
  1807.                     flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1808.                 }
  1809.                 else
  1810.                 {
  1811.                     clr_cmd ();
  1812.                     mv_cursor (0, 24);  printf (" Convolution failed. Enter any key... ");
  1813.                     wait_key ();
  1814.                 }
  1815.             }
  1816.             break;
  1817.  
  1818.         case 'O':            /* orig/transform toggle */
  1819.         case 'o':
  1820.              clr_cmd ();
  1821.             mv_cursor (0, 24);
  1822.             if (orig)
  1823.             {
  1824.                 orig  = 0;
  1825.                 Beta  = 0;
  1826.                 Noise = 0;
  1827.                 printf (" Transforms on new image. Beta,Noise reset. Enter any key... ");
  1828.                 wait_key ();
  1829.             }
  1830.             else
  1831.             {
  1832.                 orig  = 1;
  1833.                 Beta  = 0;
  1834.                 Noise = 0;
  1835.                 printf (" Transforms on original image. Beta,Noise reset. Enter any key... ");
  1836.                 wait_key ();
  1837. /*                printf ("Copying original to transform array...");*/
  1838. /*                copyrast (Raster, Width, Height, TransRast);*/
  1839.             }
  1840.             break;
  1841.  
  1842.         case ' ':
  1843.             if (orig)
  1844.             {
  1845.                 clr_screen ();
  1846.                 flicker (Raster, Width, Height, Beta, Noise, 1);
  1847.             }
  1848.             else
  1849.             {
  1850.                 clr_screen ();
  1851.                 flicker (TransRast, NewWidth, NewHeight, Beta, Noise, 1);
  1852.             }
  1853.             break;
  1854.  
  1855.         default:
  1856.             clr_cmd ();
  1857.             mv_cursor (0, 24);
  1858.             printf (" Unknown command. Type ? for help. Enter any key... ");
  1859.             wait_key ();
  1860.             break;
  1861.         }
  1862.     }
  1863.  
  1864. endloop:
  1865.  
  1866.  
  1867.     if (check_key ())
  1868.         exit (1);
  1869.  
  1870.     return (!0);
  1871. }
  1872.  
  1873.  
  1874.  
  1875.  
  1876. /*------------------------------*/
  1877. /*    cmaptoint        */
  1878. /*------------------------------*/
  1879. cmaptoint (pras, w, h, map, useNTSC)
  1880. uchar_t           *pras;
  1881. int        w;
  1882. int        h;
  1883. uchar_t        map[MAPSIZ][3];
  1884. int        useNTSC;
  1885. {
  1886.  
  1887. /*
  1888.  *    convert image (in place) from colormap index to intensity. input
  1889.  *    contains pointer into a colormap. output will contain intensity
  1890.  *    either simple average or using NTSC formula. values will lie
  1891.  *    between 0 and 255, inclusive. array should be declared unsigned
  1892.  *    char.
  1893.  */
  1894.  
  1895.     register uchar_t       *pr;
  1896.     register uchar_t       *pmap;
  1897.     register long        rpl;
  1898.     register long        gpl;
  1899.     register long        bpl;
  1900.     register uint_t        c;
  1901.     register long        val;
  1902.     long            ii;
  1903.     long            lim;
  1904.  
  1905.  
  1906.     lim  = (long) w * (long) h;
  1907.     pr   = pras;
  1908.     pmap = &(map[0][0]);
  1909.     for (ii = 0L; ii < lim; ii++)
  1910.     {
  1911.         c   = (uint_t) (*pr);
  1912. #if 0
  1913.         rpl = (ulong_t) (map[c][0]);
  1914.         gpl = (ulong_t) (map[c][1]);
  1915.         bpl = (ulong_t) (map[c][2]);
  1916. #else
  1917.         rpl = (ulong_t) (pmap[(3*c)    ]);
  1918.         gpl = (ulong_t) (pmap[(3*c) + 1]);
  1919.         bpl = (ulong_t) (pmap[(3*c) + 2]);
  1920. #endif
  1921.         if (useNTSC)
  1922.             val = ((rpl*30L) + (gpl*59L) + (bpl*11L)) / 100L;
  1923.         else
  1924.             val = (rpl + gpl + bpl) / 3L;
  1925.  
  1926.         if (val > 255)
  1927.             val = 255;
  1928.         if (val < 0)
  1929.             val = 0;
  1930.  
  1931.         *pr++ = (uchar_t) val;
  1932.     }
  1933. }
  1934.  
  1935.  
  1936.  
  1937.  
  1938. /*------------------------------*/
  1939. /*    showfl            */
  1940. /*------------------------------*/
  1941. int showfl (s0)
  1942. int    *s0;
  1943. {
  1944.  
  1945. /*
  1946.  *    show a flicker image already in memory. for 640x400 ONLY!!!
  1947.  *    returns char read to stop the display as low byte of int.
  1948.  */
  1949.  
  1950.     register long    ii;
  1951.     register char  *ps1;
  1952.     register char  *ps2;
  1953.     char           *old1;
  1954.     char           *old2;
  1955.     int           *s1, *s2, *s3;
  1956.     long        ret;
  1957.  
  1958.  
  1959.  
  1960.     /*
  1961.      *   remember old screen
  1962.      */
  1963.     old1 = Logbase ();
  1964.     old2 = Physbase ();
  1965.  
  1966.  
  1967.  
  1968.     /*
  1969.      *   clear these (phys and logical)
  1970.      */
  1971.     ps1 = old1;
  1972.     ps2 = old2;
  1973.     for (ii = 0L; ii < 32000L; ii++)
  1974.     {
  1975.         *ps1++ = 0;
  1976.         *ps2++ = 0;
  1977.     }
  1978.  
  1979.  
  1980.  
  1981.     /*
  1982.      *   set phys screen to first screen
  1983.      */
  1984.     Setscreen (old2, s0, -1);
  1985.  
  1986.  
  1987.  
  1988.     /*
  1989.      *   set pointers
  1990.      */
  1991.     s1 = (int *) Physbase ();
  1992.     s2 = (int *) ((long) s1 + 32000L);
  1993.     s3 = (int *) ((long) s2 + 32000L);
  1994.  
  1995.  
  1996.  
  1997.     /*
  1998.      *   display until a key is pressed
  1999.      */
  2000.     do
  2001.     {
  2002.         Setscreen (old2, s1, -1);    Vsync ();
  2003.         Setscreen (old2, s2, -1);    Vsync ();
  2004.         Setscreen (old2, s3, -1);    Vsync ();
  2005.  
  2006.     } while (!Bconstat (2));
  2007.  
  2008.  
  2009.  
  2010.     /*
  2011.      *   get the key...
  2012.      */
  2013.     ret = Bconin (2) & 0x000000ffL;
  2014.  
  2015.  
  2016.  
  2017.     /*
  2018.      *   reset screen
  2019.      */
  2020.     Setscreen (old1, old2, -1);
  2021.  
  2022.  
  2023.  
  2024.     /*
  2025.      *   clear keypresses
  2026.      */
  2027.     while (Bconstat (2))
  2028.         Bconin (2);
  2029.  
  2030.  
  2031.     /*
  2032.      *   done.
  2033.      */
  2034.     return ((int) ret);
  2035. }
  2036.  
  2037.  
  2038.  
  2039.  
  2040. /*------------------------------*/
  2041. /*    title            */
  2042. /*------------------------------*/
  2043. void title (b)
  2044. int    b;
  2045. {
  2046.  
  2047.  clr_screen ();
  2048.  cursor (0);
  2049.  
  2050.  if (!b)
  2051.  {
  2052.   mv_cursor (10, 10);
  2053.   printf ("%s", version);
  2054.   mv_cursor (10, 12);
  2055.   printf ("GIF file is first read then displayed.  Mode initially set");
  2056.   mv_cursor (10, 13);
  2057.   printf ("to apply successive transforms to image.  Use \"o\" to apply");
  2058.   mv_cursor (10, 14);
  2059.   printf ("transforms independently to original image.   Pick options");
  2060.   mv_cursor (10, 15);
  2061.   printf ("from menu at prompt.  Use \"?\" to get help.  If you plan to");
  2062.   mv_cursor (10, 16);
  2063.   printf ("rotate an image, it is probably best to do that first.");
  2064.  
  2065.   mv_cursor (10, 18);
  2066.   printf ("Press any key to continue...");
  2067.  
  2068.   wait_key ();        /* wait for a keypress... */
  2069.  }
  2070. }
  2071.  
  2072.  
  2073.  
  2074.  
  2075. /*------------------------------*/
  2076. /*    conv_menu        */
  2077. /*------------------------------*/
  2078. void conv_menu (opt)
  2079. int    opt;
  2080. {
  2081.  if (opt == 1)
  2082.  {
  2083.   clr_screen ();
  2084.   mv_cursor (0, 0);
  2085.   printf ("                         Built-in Convolution Kernels:\n");
  2086.   printf ("\n");
  2087.   printf ("  ------------ Low Pass Filter --------------   ----- High Pass Filter -----\n");
  2088.   printf ("  1/9 1/9 1/9  1/10 1/10 1/10  1/16 2/16 1/16   -1 -1 -1   0 -1  0   1 -2  1\n");
  2089.   printf ("  1/9 1/9 1/9  1/10 2/10 1/10  2/16 4/16 2/16   -1  9 -1  -1  5 -1  -2  5 -2\n");
  2090.   printf ("  1/9 1/9 1/9  1/10 1/10 1/10  1/16 2/16 1/16   -1 -1 -1   0 -1  0   1 -2  1\n");
  2091.   printf ("      [1]            [2]             [3]           [4]       [5]       [6]\n");
  2092.   printf (" -- Shift and Difference Edge --\n");
  2093.   printf (" Vertical  Horizontal Hor and Ver   ------------- Laplace Edge -------------\n");
  2094.   printf ("  0  0  0    0 -1  0   -1  0  0     0  1  0   -1 -1 -1   -1 -1 -1    1 -2  1\n");
  2095.   printf (" -1  1  0    0  1  0    0  1  0     1 -4  1   -1  8 -1   -1  9 -1   -2  4 -2\n");
  2096.   printf ("  0  0  0    0  0  0    0  0  0     0  1  0   -1 -1 -1   -1 -1 -1    1 -2  1\n");
  2097.   printf ("    [7]        [8]        [9]         [10]       [11]       [12]       [13]\n");
  2098.   printf (" ------------------------ Gradient Directional Edge -----------------------\n");
  2099.   printf ("   North    Northeast    East     Southeast    South    Southwest     West\n");
  2100.   printf ("  1  1  1    1  1  1   -1  1  1   -1 -1  1   -1 -1 -1    1 -1 -1    1  1 -1\n");
  2101.   printf ("  1 -2  1   -1 -2  1   -1 -2  1   -1 -2  1    1 -2  1    1 -2 -1    1 -2 -1\n");
  2102.   printf (" -1 -1 -1   -1 -1  1   -1  1  1    1  1  1    1  1  1    1  1  1    1  1 -1\n");
  2103.   printf ("    [14]       [15]       [16]       [17]       [18]       [19]       [20]\n");
  2104.   printf (" Northwest\n");
  2105.   printf ("  1  1  1\n");
  2106.   printf ("  1 -2 -1      Choose a filter (numbers in \"[]\" below kernels).\n");
  2107.   printf ("  1 -1 -1      For user-defined, enter 0. You will be prompted for values.\n");
  2108.   printf ("    [21]\n");
  2109.  }
  2110.  else if (opt == 2)
  2111.  {
  2112.   clr_screen ();
  2113.   mv_cursor (0, 0);
  2114.   printf ("\n");
  2115.   printf (" The convolution kernel is a 3x3 matrix which is applied to a\n");
  2116.   printf (" 3x3 neighborhood of a pixel and looks like this:\n");
  2117.   printf ("\n");
  2118.   printf ("       __          __ \n");
  2119.   printf ("      |              |\n");
  2120.   printf ("      | k0   k1   k2 |\n");
  2121.   printf ("      |              |\n");
  2122.   printf ("      | k3   k4   k5 |\n");
  2123.   printf ("      |              |\n");
  2124.   printf ("      | k6   k7   k8 |\n");
  2125.   printf ("      |__          __|\n");
  2126.   printf ("\n\n");
  2127.   printf (" You also need to specify if there is a resultant multiplyer or\n");
  2128.   printf (" divisor. The operation on pixels (p4 is target or center) is:\n");
  2129.   printf ("\n");
  2130.   printf (" p4 =  (p0 * k0) + ... + (p8 * k8)         ( 0, no scaling)\n");
  2131.   printf (" p4 = ((p0 * k0) + ... + (p8 * k8)) * mult ( 1, with multiplier)\n");
  2132.   printf (" p4 = ((p0 * k0) + ... + (p8 * k8)) / div  (-1, with divisor)\n");
  2133.   printf ("\n");
  2134.  }
  2135. }
  2136.  
  2137.  
  2138.  
  2139.  
  2140. /*------------------------------*/
  2141. /*    info            */
  2142. /*------------------------------*/
  2143. void info (fname)
  2144. char   *fname;
  2145. {
  2146. int    key;
  2147. long    size;
  2148.  
  2149. clr_screen ();
  2150. mv_cursor (0, 1);
  2151.  
  2152. printf (" MGIF Version:    %s\n", version);
  2153. printf (" \n");
  2154. printf (" File:            %s\n", fname);
  2155. printf (" \n");
  2156. size = (long) Width * (long) Height;
  2157. printf (" Original image:\n");
  2158. printf ("          Width   %6d\n", Width);
  2159. printf ("          Height  %6d\n", Height);
  2160. printf ("          Size    %6ld pixels\n", size);
  2161. printf (" \n");
  2162. size = (long) Width * (long) Height;
  2163. printf (" New/transformed image:\n");
  2164. printf ("          Width   %6d\n", NewWidth);
  2165. printf ("          Height  %6d\n", NewHeight);
  2166. printf ("          Size    %6ld pixels\n", size);
  2167.  
  2168. }
  2169.  
  2170.  
  2171.  
  2172.  
  2173. /*------------------------------*/
  2174. /*    do_help            */
  2175. /*------------------------------*/
  2176. void do_help ()
  2177. {
  2178. int    key;
  2179.  
  2180. clr_screen ();
  2181. mv_cursor (0, 1);
  2182.  
  2183. printf (" MGIF Version:    %s\n", version);
  2184. printf (" \n");
  2185. printf (" Category         Key(s) Description\n");
  2186. printf (" --------------------------------------------------------------------\n");
  2187. printf (" Control:         ?      help\n");
  2188. printf ("                  w      what (info about image)\n");
  2189. printf ("                  q      quit (next image)\n");
  2190. printf ("                  ESC    exit program now\n");
  2191. printf ("                  SPACE  draw image\n");
  2192. printf ("                  hi     histogram\n");
  2193. printf ("                  o      toggle transform original/new image\n");
  2194. printf ("                  f      file operations\n");
  2195. printf ("                  cp     image copy (orig<-->new)\n");
  2196. printf (" \n");
  2197. printf (" Display Options: n      add noise (0-100 percent, 0 turns off)\n");
  2198. printf ("                  g      Laplace filter (beta,1,2,... 0 turns off)\n");
  2199.  
  2200. clr_cmd ();
  2201. mv_cursor (0, 24);
  2202. printf (" More? (y/n): ");
  2203. key = get_key ();
  2204. printf ("%c", (char) key);
  2205. if ((key == 'n') || (key == 'N'))
  2206.     return;
  2207.  
  2208. clr_screen ();
  2209. mv_cursor (0, 1);
  2210.  
  2211. printf (" MGIF Version:    %s\n", version);
  2212. printf (" \n");
  2213. printf (" Category         Key(s) Description\n");
  2214. printf (" --------------------------------------------------------------------\n");
  2215. printf (" Frame Processes: e      enlarge (2x)\n");
  2216. printf ("                  s      shrink (.5x)\n");
  2217. printf ("                  z      zoom (2x)\n");
  2218. printf ("                  cu     cut\n");
  2219. printf ("                  r      rotate (+/-90 or 180 deg)\n");
  2220. printf ("                  mi     mirror (horizontal or vertical)\n");
  2221. printf (" \n");
  2222. printf (" Point Processes: he     histogram equalization\n");
  2223. printf ("                  i      inverse (negation, 0 all points else thresh)\n");
  2224. printf ("                  l      log scaling\n");
  2225. printf ("                  t      threshold (pseudo black/white)\n");
  2226. printf ("                  co     contrast expansion (need new range)\n");
  2227. printf ("                  br     brighten (darken if negative)\n");
  2228. printf (" \n");
  2229. printf (" Area Processes:  bl     blur (3x3)\n");
  2230. printf ("                  me     median filter (3x3)\n");
  2231. printf ("                  v      convolutions (3x3)\n");
  2232.  
  2233. return;
  2234. }
  2235.  
  2236.