home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / GRAPHICS / jpegshow_2.0.lzh / JPEGSHOW / jpegshow.c < prev    next >
C/C++ Source or Header  |  1995-03-22  |  8KB  |  307 lines

  1. #include <stdio.h>
  2. #include <modes.h>
  3. #include <signal.h>
  4. typedef long size_t;
  5. #include "jpeglib.h"
  6. #include <setjmp.h>
  7. #include "getargs.h"
  8.  
  9. #define TABSIZE (sizeof(Argtab)/sizeof(ARG))
  10. #define SCREEN_WIDTH 384
  11. #define SCREEN_HEIGHT 480
  12. #define SCREEN_TYPE 9
  13. #define X_MAX 45
  14. #define Y_MAX 56
  15.  
  16. int actwin, signum, pauselen = -1;
  17. int iflag, xflag, yflag, scale = 1, sflag, vflag, wflag, gflag, mflag, dflag;
  18. int xoffset, yoffset, gotsig;
  19. extern errno;
  20. extern int h_pos, v_pos;
  21. unsigned char *scraddr, *sptr, *ptr;
  22. int row_stride;              /* physical row width in output buffer */
  23. JSAMPARRAY buffer;           /* Output row buffer */
  24. struct jpeg_decompress_struct cinfo;
  25.  
  26. struct my_error_mgr {
  27.    struct jpeg_error_mgr pub;   /* "public" fields */
  28.    jmp_buf setjmp_buffer;       /* for return to caller */
  29. };
  30.  
  31. ARG Argtab[] =
  32. {{'i', BOOLEAN, &iflag, "display header info only"},
  33.  {'d', INTEGER, &dflag, "debug level"},
  34.  {'g', BOOLEAN, &gflag, "grayscale output"},
  35.  {'m', BOOLEAN, &mflag, "mouse scrolling"},
  36.  {'p', INTEGER, &pauselen, "pause in secs (0 = no pause, -1= wait for user"},
  37.  {'s', INTEGER, &scale, "scale factor, must be 1, 2, 4 or 8"},
  38.  {'v', BOOLEAN, &vflag, "verbose"},
  39.  {'x', INTEGER, &xflag, "x offset in percent"},
  40.  {'y', INTEGER, &yflag, "y offset in percent"},
  41.  {'1', BOOLEAN, &sflag, "single pass (fast)"}};
  42.  
  43. typedef struct my_error_mgr *my_error_ptr;
  44.  
  45. unsigned char palette[3][256];
  46.  
  47. gotsignl(int signum)
  48. {
  49.    gotsig = signum;
  50.  
  51.    if (signum != SIGQUIT && signum != SIGINT)
  52.       return;
  53.  
  54.    jpeg_destroy_decompress(&cinfo);
  55.    Select(0);
  56.    exit(signum);
  57. }
  58.  
  59. void wait4user()
  60. {
  61.    char c;
  62.  
  63.    if (pauselen > 0)
  64.       sleep(pauselen);
  65.    else if (pauselen < 0) {
  66.       if (mflag) {
  67.          Bell(actwin);
  68.          mmenu(actwin);
  69.       } else {
  70.          Bell(actwin);
  71.          do {
  72.             read(actwin, &c, 1);
  73.          } while (c != 13);
  74.       }
  75.    }
  76. }
  77.  
  78. METHODDEF void my_error_exit(j_common_ptr cinfo)
  79. {
  80.    my_error_ptr myerr = (my_error_ptr) cinfo->err;
  81.  
  82.    (*cinfo->err->output_message) (cinfo);
  83.  
  84.    longjmp(myerr->setjmp_buffer, 1);
  85. }
  86.  
  87. GLOBAL int read_JPEG_file(char *filename)
  88. {
  89.    struct my_error_mgr jerr;
  90.    FILE *infile;                /* source file */
  91.    int i;
  92.  
  93.    if ((infile = fopen(filename, "r")) == NULL) {
  94.       fprintf(stderr, "can't open %s\n", filename);
  95.       return 0;
  96.    }
  97.  
  98.    if (mflag)
  99.         _ss_tbar(actwin, filename);
  100.  
  101.    cinfo.err = jpeg_std_error(&jerr.pub);
  102.    jerr.pub.error_exit = my_error_exit;
  103.  
  104.    if (setjmp(jerr.setjmp_buffer)) {
  105.       jpeg_destroy_decompress(&cinfo);
  106.       Select(0);
  107.       fclose(infile);
  108.       return 0;
  109.    }
  110.    jpeg_create_decompress(&cinfo);
  111.  
  112.    jpeg_stdio_src(&cinfo, infile);
  113.  
  114.    (void) jpeg_read_header(&cinfo, TRUE);
  115.    cinfo.quantize_colors = TRUE;
  116.    cinfo.scale_num = 1;
  117.    cinfo.scale_denom = scale;
  118.    cinfo.err->trace_level = dflag;
  119.  
  120.    jpeg_calc_output_dimensions(&cinfo);
  121.  
  122.    row_stride = cinfo.output_width;
  123.  
  124.    if (mflag)
  125.       buffer = (*cinfo.mem->alloc_sarray)
  126.          ((j_common_ptr) & cinfo, JPOOL_IMAGE, row_stride, cinfo.output_height);
  127.    else
  128.       buffer = (*cinfo.mem->alloc_sarray)
  129.          ((j_common_ptr) & cinfo, JPOOL_IMAGE, row_stride, 1);
  130.  
  131.    if (sflag)
  132.       cinfo.two_pass_quantize = FALSE;
  133.  
  134.    if (gflag)
  135.       cinfo.out_color_space = JCS_GRAYSCALE;
  136.  
  137.    if (mflag)
  138.       cinfo.desired_number_of_colors = 251;
  139.  
  140.    jpeg_start_decompress(&cinfo);
  141.  
  142.    if (iflag || vflag) {
  143.       fprintf(stderr, "output width x height = %d x %d\n",
  144.               cinfo.output_width, cinfo.output_height);
  145.       fprintf(stderr, "actual number of colors = %d\n",
  146.               cinfo.actual_number_of_colors);
  147.    }
  148.    if (iflag) {
  149.       jpeg_destroy_decompress(&cinfo);
  150.       return 0;
  151.    }
  152.    xoffset = xflag * cinfo.output_width / 100;
  153.    yoffset = yflag * cinfo.output_height / 100;
  154.  
  155.    if ( cinfo.out_color_space == JCS_GRAYSCALE )
  156.       for (i = 0; i < cinfo.desired_number_of_colors; i++)
  157.          Palette(actwin, i,
  158.              cinfo.colormap[0][i], cinfo.colormap[0][i], cinfo.colormap[0][i]);
  159.    else
  160.       for (i = 0; i < cinfo.desired_number_of_colors; i++)
  161.          Palette(actwin, i,
  162.              cinfo.colormap[0][i], cinfo.colormap[1][i], cinfo.colormap[2][i]);
  163.  
  164.    ptr = buffer[0];
  165.  
  166.    while (cinfo.output_scanline < cinfo.output_height) {
  167.       (void) jpeg_read_scanlines(&cinfo, &ptr, 1);
  168.  
  169.       if (mflag) {
  170.          put_scanline_m(ptr, row_stride, cinfo.output_scanline);
  171.          ptr += row_stride;
  172.       } else
  173.          put_scanline(ptr, row_stride);
  174.    }
  175.  
  176.    (void) jpeg_finish_decompress(&cinfo);
  177.  
  178.    jpeg_destroy_decompress(&cinfo);
  179.  
  180.    fclose(infile);
  181.  
  182.    return 1;
  183. }
  184.  
  185. main(int argc, char **argv)
  186. {
  187.    argc = getargs(argc, argv, Argtab, TABSIZE);
  188.  
  189.    if (scale != 1 && scale != 2 && scale != 4 && scale != 8) {
  190.       fprintf(stderr, "scale = %d, must be 1, 2, 4 or 8 - ignored\n", scale);
  191.       scale = 1;
  192.    }
  193.    if (xflag < 0 || xflag >= 100) {
  194.       fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", xflag);
  195.       xflag = 0;
  196.    }
  197.    if (yflag < 0 || yflag >= 100) {
  198.       fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", yflag);
  199.       yflag = 0;
  200.    }
  201.    if (!iflag) {
  202.       actwin = open("/w", S_IWRITE | S_IREAD);
  203.       if (actwin == EOF)
  204.          exit(_errmsg(errno, "cannot open '/w'\n"));
  205.  
  206.       if (DWSet(actwin, SCREEN_TYPE, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT / 8,
  207.                 0, 0, 0) == EOF)
  208.          exit(_errmsg(errno, "cannot DWSet\n"));
  209.  
  210.       CurOff(actwin);
  211.       ScaleSw(actwin, 0);
  212.       Select(actwin);
  213.  
  214.       scraddr = (unsigned char *) _gs_scadd(actwin);
  215.       if (scraddr == NULL)
  216.          exit(_errmsg(errno, "cannot _gs_scadd\n"));
  217.  
  218.       if (mflag) {
  219.          scraddr += 16 * SCREEN_WIDTH + 8;
  220.          openwin(actwin);
  221.       }
  222.    } else
  223.       sflag = 1;
  224.  
  225.    intercept(gotsignl);
  226.  
  227.    while (--argc > 0) {
  228.       sptr = scraddr;
  229.       if (!iflag)
  230.          Clear(actwin);
  231.       h_pos = v_pos = 0;
  232.       _ss_sbar(actwin, h_pos, v_pos);
  233.       if (read_JPEG_file(*++argv) == 0)
  234.          continue;
  235.       wait4user();
  236.    }
  237.  
  238.    Select(0);
  239. }
  240.  
  241. put_scanline(unsigned char *a, int r_s)
  242. {
  243.    register int count;
  244.    register unsigned char *dest, *src, *next;
  245.  
  246.    r_s -= xoffset;
  247.  
  248.    if (cinfo.output_scanline < yoffset ||
  249.        cinfo.output_scanline - yoffset > SCREEN_HEIGHT / 2 || r_s < 0)
  250.       return;
  251.  
  252.    count = (r_s < SCREEN_WIDTH) ? r_s : SCREEN_WIDTH;
  253.    dest = sptr;
  254.    next = dest + SCREEN_WIDTH;
  255.    src = a + xoffset;
  256.    while (count--)
  257.       *dest++ = *next++ = *src++;
  258.  
  259.  
  260.    sptr += SCREEN_WIDTH * 2;
  261. }
  262.  
  263. put_scanline_m(unsigned char *a, int r_s, int n)
  264. {
  265.    register int count;
  266.    register unsigned char *dest, *src, *next;
  267.  
  268.    r_s -= xoffset;
  269.  
  270.    if (n < yoffset || n - yoffset > (SCREEN_HEIGHT - 24) / 2 || r_s < 0)
  271.       return;
  272.  
  273.    count = (r_s < SCREEN_WIDTH - 16) ? r_s : SCREEN_WIDTH - 16;
  274.    dest = sptr;
  275.    next = dest + SCREEN_WIDTH;
  276.    src = a + xoffset;
  277.    while (count--)
  278.       *dest++ = *next++ = *src++;
  279.  
  280.    sptr += SCREEN_WIDTH * 2;
  281. }
  282.  
  283. int repaint(int x, int y)
  284. {
  285.     register int i;
  286.  
  287.     if ( cinfo.output_width < SCREEN_WIDTH - 16 && x > 0 )
  288.        return 0;
  289.  
  290.     if ( cinfo.output_height < SCREEN_HEIGHT / 2 - 12 && y > 0 )
  291.        return 0;
  292.     
  293.     xoffset = x * (cinfo.output_width - SCREEN_WIDTH + 16) / X_MAX;
  294.     yoffset = y * (cinfo.output_height - SCREEN_HEIGHT / 2 + 12) / Y_MAX;
  295.  
  296.     ptr = buffer[0];
  297.     sptr = scraddr;
  298.     Clear(actwin);
  299.  
  300.     for ( i = 0; i < cinfo.output_height; i++ ) {
  301.         put_scanline_m(ptr, row_stride, i);
  302.         ptr += row_stride;
  303.     }
  304.     
  305.     return 1;
  306. }
  307.