home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / sun / rlelib / rle_cp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-15  |  5.3 KB  |  204 lines

  1. /*
  2.  * This software is copyrighted as noted below.  It may be freely copied,
  3.  * modified, and redistributed, provided that the copyright notice is 
  4.  * preserved on all copies.
  5.  * 
  6.  * There is no warranty or other guarantee of fitness for this software,
  7.  * it is provided solely "as is".  Bug reports or fixes may be sent
  8.  * to the author, who may or may not act on them as he desires.
  9.  *
  10.  * You may not include this software in a program or other software product
  11.  * without supplying the source, or without informing the end-user that the 
  12.  * source is available for no extra charge.
  13.  *
  14.  * If you modify this software, you should include a notice giving the
  15.  * name of the person performing the modification, the date of modification,
  16.  * and the reason for such modification.
  17.  */
  18. /* 
  19.  * rle_cp.c - Copy the contents of one RLE image file to another.
  20.  * 
  21.  * Author:    Spencer W. Thomas
  22.  *         EECS Dept.
  23.  *         University of Michigan
  24.  * Date:    Wed Jun 27 1990
  25.  * Copyright (c) 1990, University of Michigan
  26.  */
  27.  
  28. #include <rle.h>
  29. #include <rle_code.h>
  30. #include <rle_put.h>
  31.  
  32. /* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */
  33. #define VAXSHORT( var, fp )\
  34.     { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; }
  35.   
  36. /* Instruction format -- first byte is opcode, second is datum. */
  37.  
  38. #define OPCODE(inst) (inst[0] & ~LONG)
  39. #define LONGP(inst) (inst[0] & LONG)
  40. #define DATUM(inst) (inst[1] & 0xff)    /* Make sure it's unsigned. */
  41.  
  42. /* Write a two-byte value in little_endian order. */
  43. #define    put16(a)    (putc((a)&0xff,outfile),putc(((a)>>8)&0xff,outfile))
  44.  
  45. /*****************************************************************
  46.  * TAG( rle_cp )
  47.  * 
  48.  * Copy the image described by in_hdr to that described by out_hdr
  49.  * until an end-of-image is encountered.
  50.  *
  51.  * Replaces the fread/fwrite loop used that was before we were
  52.  * concerned with concatenated images.
  53.  * 
  54.  * Inputs:
  55.  *     in_hdr:        Describes input image.
  56.  * Outputs:
  57.  *     out_hdr:    Describes output image.
  58.  * Assumptions:
  59.  *     rle_get_setup/rle_put_setup have been called.
  60.  *     in_hdr and out_hdr are compatible -- same number of channels,
  61.  *     same size, all relevant channel bits set.
  62.  *     The scanline most recently read from the input has been
  63.  *     written to the output.
  64.  * Algorithm:
  65.  *     Minimal processing is done.  Each opcode is recognized to the
  66.  *     extent necessary to copy it and its data to the output.
  67.  */
  68. void
  69. rle_cp( in_hdr, the_hdr )
  70. rle_hdr *in_hdr;
  71. rle_hdr *the_hdr;
  72. {
  73.     register FILE *infile = in_hdr->rle_file;
  74.     register FILE *outfile = the_hdr->rle_file;
  75.     char inst[2];
  76.     short nc, buflen;
  77.     char *buffer;
  78.  
  79.     /* Add in vertical skip from last scanline */
  80.     if ( in_hdr->priv.get.vert_skip > 0 )
  81.     {
  82.     in_hdr->priv.get.scan_y += in_hdr->priv.get.vert_skip;
  83.     if ( in_hdr->priv.get.vert_skip > 1 )
  84.         rle_skiprow( the_hdr, in_hdr->priv.get.vert_skip - 1 );
  85.     }
  86.  
  87.     if ( in_hdr->priv.get.is_eof )
  88.     {
  89.     rle_puteof( the_hdr );
  90.     return;
  91.     }
  92.  
  93.     if ( the_hdr->priv.put.nblank > 0 )
  94.     {
  95.     SkipBlankLines( the_hdr->priv.put.nblank );
  96.     the_hdr->priv.put.nblank = 0;
  97.     }
  98.  
  99.     /* Allocate memory for reading byte data. */
  100.     buflen = in_hdr->xmax - in_hdr->xmin + 2;
  101.     buffer = (char *)malloc( buflen );
  102.  
  103.     /* Otherwise, read and write instructions until an EOF
  104.      * instruction is encountered.
  105.      */
  106.     for (;;)
  107.     {
  108.         inst[0] = getc( infile );
  109.     inst[1] = getc( infile );
  110.  
  111.     /* Don't 'put' the instruction until we know what it is. */
  112.     if ( feof(infile) )
  113.     {
  114.         in_hdr->priv.get.is_eof = 1;
  115.         rle_puteof( the_hdr );
  116.         break;        /* <--- one of the exits */
  117.     }
  118.  
  119.     switch( OPCODE(inst) )
  120.     {
  121.     case RSkipLinesOp:
  122.         putc( inst[0], outfile );
  123.         putc( inst[1], outfile );
  124.         if ( LONGP(inst) )
  125.         {
  126.         putc( getc( infile ), outfile );
  127.         putc( getc( infile ), outfile );
  128.         }
  129.         break;            /* need to break for() here, too */
  130.  
  131.     case RSetColorOp:
  132.         putc( inst[0], outfile );
  133.         putc( inst[1], outfile );
  134.         break;
  135.  
  136.     case RSkipPixelsOp:
  137.         putc( inst[0], outfile );
  138.         putc( inst[1], outfile );
  139.         if ( LONGP(inst) )
  140.         {
  141.         putc( getc( infile ), outfile );
  142.         putc( getc( infile ), outfile );
  143.         }
  144.         break;
  145.  
  146.     case RByteDataOp:
  147.         putc( inst[0], outfile );
  148.         putc( inst[1], outfile );
  149.         if ( LONGP(inst) )
  150.         {
  151.             VAXSHORT( nc, infile );
  152.         put16( nc );
  153.         }
  154.         else
  155.         nc = DATUM(inst);
  156.         nc++;
  157.         nc = 2 * ((nc + 1) / 2);
  158.         /* Total paranoia.  nc should never be > buflen. */
  159.         while ( nc > buflen )
  160.         {
  161.         fread( buffer, nc, 1, infile );
  162.         fwrite( buffer, nc, 1, outfile );
  163.         nc -= buflen;
  164.         }
  165.  
  166.         fread( buffer, nc, 1, infile );
  167.         fwrite( buffer, nc, 1, outfile );
  168.         break;
  169.  
  170.     case RRunDataOp:
  171.         putc( inst[0], outfile );
  172.         putc( inst[1], outfile );
  173.         if ( LONGP(inst) )
  174.         {
  175.         putc( getc( infile ), outfile );
  176.         putc( getc( infile ), outfile );
  177.         }
  178.  
  179.         putc( getc( infile ), outfile );
  180.         putc( getc( infile ), outfile );
  181.         break;
  182.  
  183.     case REOFOp:
  184.         in_hdr->priv.get.is_eof = 1;
  185.         rle_puteof( the_hdr );
  186.         break;
  187.  
  188.     default:
  189.         fprintf( stderr, "rle_cp: Unrecognized opcode: %d\n",
  190.              OPCODE(inst) );
  191.         fflush( the_hdr->rle_file );
  192.         exit(1);
  193.     }
  194.     if ( OPCODE(inst) == REOFOp )
  195.         break;            /* <--- the other loop exit */
  196.     }
  197.  
  198.     /* Just in case the caller does something silly like calling rle_getrow. */
  199.     in_hdr->priv.get.scan_y = in_hdr->ymax;
  200.     in_hdr->priv.get.vert_skip = 0;
  201.  
  202.     return;
  203. }
  204.