home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / CMDS / pcxview_mm1.lzh / PCXVIEW / pcxview.c < prev    next >
C/C++ Source or Header  |  1997-12-15  |  7KB  |  311 lines

  1. #include <stdio.h>
  2. #include <modes.h>
  3. #include <types.h>
  4. #include <signal.h>
  5. #include "getargs.h"
  6. extern errno;
  7. extern char *pixels, *pcxpixels;
  8. extern int Width, Height;
  9. extern short BytesPerLine;
  10.  
  11. #define TABSIZE (sizeof(Argtab)/sizeof(ARG))
  12.  
  13. int actwin = -1, oldfile, signum, pauselen = -1;
  14. int iflag, hflag, xflag, yflag, mflag, scale = 1;
  15. int xoffset, yoffset, ny;
  16. short h_pos, v_pos, ncolors, gotsig;
  17. short screen_type, screen_width, screen_height, x_max, y_max, factor;
  18.  
  19. unsigned char *scraddr, *sptr, *scrend;
  20. unsigned char colormap[256][3];
  21.  
  22. ARG Argtab[] =
  23. {{'h', BOOLEAN, &hflag, "display header info only"},
  24.  {'i', BOOLEAN, &iflag, "read file from standard input"},
  25.  {'m', BOOLEAN, &mflag, "mouse scrolling"},
  26.  {'p', INTEGER, &pauselen, "pause in secs (0 = no pause, -1= wait for user)"},
  27.  {'s', INTEGER, &scale, "scale factor, must be 1 or 2"},
  28.  {'x', INTEGER, &xflag, "x offset in percent"},
  29.  {'y', INTEGER, &yflag, "y offset in percent"},
  30. };
  31.  
  32. gotsignl(signum)
  33. {
  34.    gotsig = signum;
  35.  
  36.    if (signum != SIGQUIT && signum != SIGINT)
  37.       return;
  38.  
  39.    Select(0);
  40.    exit(signum);
  41. }
  42.  
  43. int wait4user(argc, argv)
  44. int argc;
  45. char **argv;
  46. {
  47.    char c;
  48.  
  49.    MCurOn(actwin);
  50.    if (pauselen > 0)
  51.       sleep(pauselen);
  52.    else if (pauselen < 0) {
  53.       if (mflag) {
  54.          _ss_sbar(actwin, h_pos, v_pos);
  55.          Bell(actwin);
  56.          return mmenu(actwin, argc, argv);
  57.       } else {
  58.          Bell(actwin);
  59.          do {
  60.             read(actwin, &c, 1);
  61.          } while (c != 13);
  62.       }
  63.    }
  64.    return 0;
  65. }
  66.  
  67. main(argc, argv)
  68. int argc;
  69. char **argv;
  70. {
  71.    int res, i;
  72.    register int y;
  73.  
  74.    argc = getargs(argc, argv, Argtab, TABSIZE);
  75.  
  76.    if (argc < 2 && !iflag)
  77.       usage();
  78.  
  79.    if ( scale != 1 && scale != 2 ) {
  80.       fprintf(stderr, "scale %d must be 1 or 2 - ignored\n", scale);
  81.       scale = 1;
  82.    }
  83.  
  84.    if (xflag < 0 || xflag >= 100) {
  85.       fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", xflag);
  86.       xflag = 0;
  87.    }
  88.    if (yflag < 0 || yflag >= 100) {
  89.       fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", yflag);
  90.       yflag = 0;
  91.    }
  92.    intercept(gotsignl);
  93.  
  94.    if ( iflag )
  95.       argc++;
  96.  
  97.    for (i = 1; i < argc; i++) {
  98.       pcx_read(argv[i]);
  99.  
  100.       screen_width = 384;
  101.       screen_height = 480;
  102.       y_max = 56;
  103.  
  104.       if (ncolors > 16) {
  105.          screen_type = 9;
  106.          x_max = 45;
  107.          factor = 3 - scale;
  108.       } else {
  109.          screen_type = 7;
  110.          x_max = 93;
  111.          factor = 1;
  112.       }
  113.  
  114.       if (!hflag) {
  115.          oldfile = actwin;
  116.          actwin = open("/w", S_IWRITE | S_IREAD);
  117.          if (actwin == EOF)
  118.             exit(_errmsg(errno, "cannot open '/w'\n"));
  119.  
  120.          DWEnd(actwin);
  121.          if (DWSet(actwin, screen_type, 0, 0, x_max + 3, screen_height / 8,
  122.                    0, 0, 0) == EOF)
  123.             exit(_errmsg(errno, "cannot DWSet\n"));
  124.  
  125.          CurOff(actwin);
  126.          ScaleSw(actwin, 0);
  127.  
  128.          scraddr = (unsigned char *) _gs_scadd(actwin);
  129.          if (scraddr == NULL)
  130.             exit(_errmsg(errno, "cannot _gs_scadd\n"));
  131.  
  132.          scrend = scraddr + screen_width*screen_height;
  133.          if (!hflag) {
  134.             h_pos = v_pos = 0;
  135.             Clear(actwin);
  136.             _ss_sbar(actwin, h_pos, v_pos);
  137.          }
  138.       } else
  139.          continue;
  140.  
  141.       xoffset = xflag * Width / 100;
  142.       yoffset = yflag * Height / 100;
  143.       if ( ncolors <= 16 )
  144.          xoffset /= 2;
  145.  
  146.       if ( _ss_palette(actwin, 0, colormap, 3 * ncolors) == -1 )
  147.          exit(_errmsg(errno, "cannot set palette\n"));
  148.  
  149.       if (mflag) {
  150.          scraddr += 16 * screen_width + 8;
  151.          openwin(actwin);
  152.          _ss_tbar(actwin, argv[i]);
  153.       }
  154.  
  155.       Select(actwin);
  156.       MCurOff(actwin);
  157.       if ( oldfile > 0 )
  158.          close(oldfile);
  159.       sptr = scraddr;
  160.       pcxpixels = pixels;
  161.  
  162.       ny = ( ncolors <= 16 && scale > 1 ) ? Height/scale : Height;
  163.       for (y = 0; y < ny; y++) {
  164.          if ( scale > 1 )
  165.             rescale(pcxpixels, Width, scale);
  166.          if (mflag)
  167.             put_scanline_m(pcxpixels, Width/scale, y);
  168.          else
  169.             put_scanline(pcxpixels, Width/scale, y);
  170.          if ( ncolors > 16 )
  171.             pcxpixels += Width;
  172.          else
  173.             pcxpixels += Width*scale;
  174.       }
  175.       res = wait4user(argc, argv);
  176.  
  177.       if (res == -1 && i > 1)
  178.          i -= 2;
  179.       if (res > 0)
  180.          i = res - 1;
  181.       free(pixels);
  182.    }
  183.    Select(0);
  184. }
  185.  
  186. put_scanline(a, r_s, n)            /* pixels -> scraddr */
  187. unsigned char *a;
  188. int r_s, n;
  189. {
  190.    register int count;
  191.    register unsigned char *dest, *src, *next;
  192.  
  193.    if ( ncolors <= 16 )
  194.       r_s /= 2;
  195.  
  196.    r_s -= xoffset;
  197.  
  198.    if (n < yoffset || n - yoffset > screen_height / factor|| r_s < 0)
  199.       return;
  200.  
  201.    count = (r_s < screen_width) ? r_s : screen_width;
  202.    dest = sptr;
  203.    src = a + xoffset;
  204.  
  205.    if ( ncolors > 16 ) {
  206.       next = dest + screen_width;
  207.       if ( scale > 1 ) {
  208.          while (count--)
  209.             *dest++ = *src++;
  210.          sptr += screen_width;
  211.       } else {
  212.          while (count--)
  213.             *dest++ = *next++ = *src++;
  214.          sptr += screen_width * 2;
  215.       }
  216.    } else {
  217.       while (count--)
  218.          *dest++ = *src++;
  219.       sptr += screen_width;
  220.    }
  221. }
  222.  
  223. put_scanline_m(a, r_s, n)            /* pixels -> scraddr */
  224. unsigned char *a;
  225. int r_s, n;
  226. {
  227.    register int count;
  228.    register unsigned char *dest, *src, *next;
  229.  
  230.    if ( ncolors <= 16 )
  231.       r_s /= 2;
  232.  
  233.    r_s -= xoffset;
  234.  
  235.    if (n < yoffset || n - yoffset > (screen_height - 24) / factor|| r_s < 0)
  236.       return;
  237.  
  238.    count = (r_s < screen_width - 16) ? r_s : screen_width - 16;
  239.    dest = sptr;
  240.    src = a + xoffset;
  241.  
  242.    if ( ncolors > 16 ) {
  243.       next = dest + screen_width;
  244.       if ( scale > 1 ) {
  245.          while (count--)
  246.             *dest++ = *src++;
  247.          sptr += screen_width;
  248.       } else {
  249.          while (count--)
  250.             *dest++ = *next++ = *src++;
  251.          sptr += screen_width * 2;
  252.       }
  253.    } else {
  254.       while (count--)
  255.          *dest++ = *src++;
  256.       sptr += screen_width;
  257.    }
  258. }
  259.  
  260. int repaint(x, y)
  261. int x, y;
  262. {
  263.    register int i;
  264.  
  265.    if (BytesPerLine < screen_width*scale - 16 && x > 0)
  266.       return 0;
  267.  
  268.    if (ny < screen_height / factor - 12 && y > 0)
  269.       return 0;
  270.  
  271.    xoffset = x * (BytesPerLine - screen_width + 16) / x_max;
  272.    yoffset = y * (ny - (screen_height - 24) / factor) / y_max;
  273.    pcxpixels = pixels;
  274.  
  275.    sptr = scraddr;
  276.    Clear(actwin);
  277.  
  278.    for (i = 0; i < ny; i++) {
  279.       put_scanline_m(pcxpixels, Width/scale, i);
  280.       if ( ncolors > 16 )
  281.          pcxpixels += Width;
  282.       else
  283.          pcxpixels += Width*scale;
  284.    }
  285.    return 1;
  286. }
  287.  
  288. usage()
  289. {
  290.    fprintf(stderr, "OS-9 PCXView 1.0 by Andrzej Kotanski\n");
  291.    fprintf(stderr, "usage: pcxview <filenames> [-<option> ...]\n");
  292.    fprintf(stderr, "       displays pcx pictures on MM/1 screen");
  293.    fprintf(stderr, "\n\n");
  294.    pr_usage(Argtab, TABSIZE);
  295.    exit(0);
  296. }
  297.  
  298. rescale(pixels, linelen, sc)
  299. register u_char *pixels;
  300. register int linelen;
  301. register int sc;
  302. {
  303.     register int i;
  304.     register u_char *ptr = pixels;
  305.  
  306.     for ( i = 0; i < linelen; i += sc ) {
  307.         *pixels++ = *ptr;
  308.         ptr += sc;
  309.     }
  310. }
  311.