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

  1. #include <stdio.h>
  2. #include <modes.h>
  3. typedef long size_t;
  4. #include "jpeglib.h"
  5. #include <setjmp.h>
  6. #include "getargs.h"
  7. #define TABSIZE (sizeof(Argtab)/sizeof(ARG))
  8. #define SCREEN_WIDTH 384
  9. #define SCREEN_HEIGHT 480
  10. #define SCREEN_TYPE 9
  11.  
  12. int actwin, signum, pauselen = -1;
  13. int iflag, xflag, yflag, scale = 1, sflag, vflag, wflag;
  14. extern errno;
  15. unsigned char *scraddr, *ptr;
  16. struct jpeg_decompress_struct cinfo;
  17.  
  18. struct my_error_mgr {
  19.    struct jpeg_error_mgr pub;   /* "public" fields */
  20.    jmp_buf setjmp_buffer;       /* for return to caller */
  21. };
  22.  
  23. ARG Argtab[] =
  24. {{'i', BOOLEAN, &iflag, "display header info only"},
  25.  {'p', INTEGER, &pauselen, "pause in secs (0 = no pause, -1= wait for user"},
  26.  {'s', INTEGER, &scale, "scale factor, must be 1, 2, 4 or 8"},
  27.  {'v', BOOLEAN, &vflag, "verbose"},
  28.  {'x', INTEGER, &xflag, "x offset in percent"},
  29.  {'y', INTEGER, &yflag, "y offset in percent"},
  30.  {'1', BOOLEAN, &sflag, "single pass (fast)"}};
  31.  
  32. typedef struct my_error_mgr *my_error_ptr;
  33.  
  34. unsigned char palette[3][256];
  35.  
  36. gotsignl(int signum)
  37. {
  38.    if (signum != 2 && signum != 3)
  39.       return;
  40.  
  41.    jpeg_destroy_decompress(&cinfo);
  42.    Select(0);
  43.    exit(signum);
  44. }
  45.  
  46. void wait4user()
  47. {
  48.    char c;
  49.  
  50.    if (pauselen > 0)
  51.       sleep(pauselen);
  52.    else if (pauselen < 0) {
  53.       Bell(actwin);
  54.       do {
  55.          read(actwin, &c, 1);
  56.       } while (c != 13);
  57.    }
  58. }
  59.  
  60. METHODDEF void my_error_exit(j_common_ptr cinfo)
  61. {
  62.    my_error_ptr myerr = (my_error_ptr) cinfo->err;
  63.  
  64.    (*cinfo->err->output_message) (cinfo);
  65.  
  66.    longjmp(myerr->setjmp_buffer, 1);
  67. }
  68.  
  69. GLOBAL int read_JPEG_file(char *filename)
  70. {
  71.    struct my_error_mgr jerr;
  72.    FILE *infile;                /* source file */
  73.    JSAMPARRAY buffer;           /* Output row buffer */
  74.    int row_stride;              /* physical row width in output buffer */
  75.    int i;
  76.  
  77.    if ((infile = fopen(filename, "r")) == NULL) {
  78.       fprintf(stderr, "can't open %s\n", filename);
  79.       return 0;
  80.    }
  81.    cinfo.err = jpeg_std_error(&jerr.pub);
  82.    jerr.pub.error_exit = my_error_exit;
  83.  
  84.    if (setjmp(jerr.setjmp_buffer)) {
  85.       jpeg_destroy_decompress(&cinfo);
  86.       Select(0);
  87.       fclose(infile);
  88.       return 0;
  89.    }
  90.    jpeg_create_decompress(&cinfo);
  91.  
  92.    jpeg_stdio_src(&cinfo, infile);
  93.  
  94.    (void) jpeg_read_header(&cinfo, TRUE);
  95.    cinfo.quantize_colors = TRUE;
  96.    cinfo.scale_num = 1;
  97.    cinfo.scale_denom = scale;
  98.    if (sflag)
  99.       cinfo.two_pass_quantize = FALSE;
  100.  
  101.    jpeg_start_decompress(&cinfo);
  102.  
  103.    if (iflag || vflag) {
  104.       fprintf(stderr, "output width x height = %d x %d\n",
  105.               cinfo.output_width, cinfo.output_height);
  106.       fprintf(stderr, "actual number of colors = %d\n", cinfo.actual_number_of_colors);
  107.    }
  108.  
  109.    if (iflag) {
  110.       jpeg_destroy_decompress(&cinfo);
  111.       return 0;
  112.    }
  113.  
  114.    xflag = xflag * cinfo.output_width / 100;
  115.    yflag = yflag * cinfo.output_height / 100;
  116.  
  117.    for (i = 0; i < 256; i++)
  118.       Palette(actwin, i,
  119.           cinfo.colormap[0][i], cinfo.colormap[1][i], cinfo.colormap[2][i]);
  120.  
  121.    row_stride = cinfo.output_width;
  122.  
  123.    buffer = (*cinfo.mem->alloc_sarray)
  124.       ((j_common_ptr) & cinfo, JPOOL_IMAGE, row_stride, 1);
  125.  
  126.    while (cinfo.output_scanline < cinfo.output_height) {
  127.       (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  128.  
  129.       put_scanline_someplace(buffer[0], row_stride);
  130.    }
  131.  
  132.    (void) jpeg_finish_decompress(&cinfo);
  133.  
  134.    jpeg_destroy_decompress(&cinfo);
  135.  
  136.    fclose(infile);
  137.  
  138.    return 1;
  139. }
  140.  
  141. main(int argc, char **argv)
  142. {
  143.    argc = getargs(argc, argv, Argtab, TABSIZE);
  144.  
  145.    if (scale != 1 && scale != 2 && scale != 4 && scale != 8) {
  146.       fprintf(stderr, "scale = %d, must be 1, 2, 4 or 8 - ignored\n", scale);
  147.       scale = 1;
  148.    }
  149.  
  150.    if ( xflag < 0 || xflag >= 100 ) {
  151.       fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", xflag);
  152.       xflag = 0;
  153.    }
  154.  
  155.    if ( yflag < 0 || yflag >= 100 ) {
  156.       fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", yflag);
  157.       yflag = 0;
  158.    }
  159.  
  160.    if (!iflag) {
  161.       actwin = open("/w", S_IWRITE | S_IREAD);
  162.       if (actwin == EOF)
  163.          exit(_errmsg(errno, "cannot open '/w'\n"));
  164.  
  165.       if (DWSet(actwin, SCREEN_TYPE, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT / 8,
  166.                 0, 0, 0) == EOF)
  167.          exit(_errmsg(errno, "cannot DWSet\n"));
  168.  
  169.       CurOff(actwin);
  170.       ScaleSw(actwin, 0);
  171.       Select(actwin);
  172.  
  173.       scraddr = (unsigned char *) _gs_scadd(actwin);
  174.       if (scraddr == NULL)
  175.          exit(_errmsg(errno, "cannot _gs_scadd\n"));
  176.    } else
  177.       sflag = 1;
  178.  
  179.    intercept(gotsignl);
  180.  
  181.    while (--argc > 0) {
  182.       ptr = scraddr;
  183.       if ( !iflag )
  184.          Clear(actwin);
  185.       if ( read_JPEG_file(*++argv) == 0 )
  186.          continue;
  187.       wait4user();
  188.    }
  189.    
  190.    Select(0);
  191. }
  192.  
  193. put_scanline_someplace(unsigned char *a, int r_s)
  194. {
  195.    register int i, count;
  196.    register unsigned char *dest, *src, *next;
  197.  
  198.    r_s -= xflag;
  199.    
  200.    if (cinfo.output_scanline < yflag ||
  201.        cinfo.output_scanline - yflag > SCREEN_HEIGHT / 2 || r_s < 0)
  202.       return;
  203.  
  204.    count = (r_s < SCREEN_WIDTH) ? r_s : SCREEN_WIDTH;
  205.    i = count;
  206.    dest = ptr;
  207.    next = dest + SCREEN_WIDTH;
  208.    src = a + xflag;
  209.    while (i--)
  210.       *dest++ = *next++ = *src++;
  211.  
  212.  
  213.    ptr += SCREEN_WIDTH * 2;
  214. }
  215.