home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / GRAPHICS / jpegshow_3.0.lzh / JPEGSHOW / jpegshow.c < prev    next >
C/C++ Source or Header  |  1995-11-27  |  9KB  |  363 lines

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