This is rle_cp.c in view mode; [Download] [Up]
/* * This software is copyrighted as noted below. It may be freely copied, * modified, and redistributed, provided that the copyright notice is * preserved on all copies. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is". Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * You may not include this software in a program or other software product * without supplying the source, or without informing the end-user that the * source is available for no extra charge. * * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. */ /* * rle_cp.c - Copy the contents of one RLE image file to another. * * Author: Spencer W. Thomas * EECS Dept. * University of Michigan * Date: Wed Jun 27 1990 * Copyright (c) 1990, University of Michigan */ #include <rle.h> #include <rle_code.h> #include <rle_put.h> /* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */ #define VAXSHORT( var, fp )\ { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; } /* Instruction format -- first byte is opcode, second is datum. */ #define OPCODE(inst) (inst[0] & ~LONG) #define LONGP(inst) (inst[0] & LONG) #define DATUM(inst) (inst[1] & 0xff) /* Make sure it's unsigned. */ /* Write a two-byte value in little_endian order. */ #define put16(a) (putc((a)&0xff,outfile),putc(((a)>>8)&0xff,outfile)) /***************************************************************** * TAG( rle_cp ) * * Copy the image described by in_hdr to that described by out_hdr * until an end-of-image is encountered. * * Replaces the fread/fwrite loop used that was before we were * concerned with concatenated images. * * Inputs: * in_hdr: Describes input image. * Outputs: * out_hdr: Describes output image. * Assumptions: * rle_get_setup/rle_put_setup have been called. * in_hdr and out_hdr are compatible -- same number of channels, * same size, all relevant channel bits set. * The scanline most recently read from the input has been * written to the output. * Algorithm: * Minimal processing is done. Each opcode is recognized to the * extent necessary to copy it and its data to the output. */ void rle_cp( in_hdr, the_hdr ) rle_hdr *in_hdr; rle_hdr *the_hdr; { register FILE *infile = in_hdr->rle_file; register FILE *outfile = the_hdr->rle_file; char inst[2]; short nc, buflen; char *buffer; /* Add in vertical skip from last scanline */ if ( in_hdr->priv.get.vert_skip > 0 ) { in_hdr->priv.get.scan_y += in_hdr->priv.get.vert_skip; if ( in_hdr->priv.get.vert_skip > 1 ) rle_skiprow( the_hdr, in_hdr->priv.get.vert_skip - 1 ); } if ( in_hdr->priv.get.is_eof ) { rle_puteof( the_hdr ); return; } if ( the_hdr->priv.put.nblank > 0 ) { SkipBlankLines( the_hdr->priv.put.nblank ); the_hdr->priv.put.nblank = 0; } /* Allocate memory for reading byte data. */ buflen = in_hdr->xmax - in_hdr->xmin + 2; buffer = (char *)malloc( buflen ); /* Otherwise, read and write instructions until an EOF * instruction is encountered. */ for (;;) { inst[0] = getc( infile ); inst[1] = getc( infile ); /* Don't 'put' the instruction until we know what it is. */ if ( feof(infile) ) { in_hdr->priv.get.is_eof = 1; rle_puteof( the_hdr ); break; /* <--- one of the exits */ } switch( OPCODE(inst) ) { case RSkipLinesOp: putc( inst[0], outfile ); putc( inst[1], outfile ); if ( LONGP(inst) ) { putc( getc( infile ), outfile ); putc( getc( infile ), outfile ); } break; /* need to break for() here, too */ case RSetColorOp: putc( inst[0], outfile ); putc( inst[1], outfile ); break; case RSkipPixelsOp: putc( inst[0], outfile ); putc( inst[1], outfile ); if ( LONGP(inst) ) { putc( getc( infile ), outfile ); putc( getc( infile ), outfile ); } break; case RByteDataOp: putc( inst[0], outfile ); putc( inst[1], outfile ); if ( LONGP(inst) ) { VAXSHORT( nc, infile ); put16( nc ); } else nc = DATUM(inst); nc++; nc = 2 * ((nc + 1) / 2); /* Total paranoia. nc should never be > buflen. */ while ( nc > buflen ) { fread( buffer, nc, 1, infile ); fwrite( buffer, nc, 1, outfile ); nc -= buflen; } fread( buffer, nc, 1, infile ); fwrite( buffer, nc, 1, outfile ); break; case RRunDataOp: putc( inst[0], outfile ); putc( inst[1], outfile ); if ( LONGP(inst) ) { putc( getc( infile ), outfile ); putc( getc( infile ), outfile ); } putc( getc( infile ), outfile ); putc( getc( infile ), outfile ); break; case REOFOp: in_hdr->priv.get.is_eof = 1; rle_puteof( the_hdr ); break; default: fprintf( stderr, "rle_cp: Unrecognized opcode: %d\n", OPCODE(inst) ); fflush( the_hdr->rle_file ); exit(1); } if ( OPCODE(inst) == REOFOp ) break; /* <--- the other loop exit */ } /* Just in case the caller does something silly like calling rle_getrow. */ in_hdr->priv.get.scan_y = in_hdr->ymax; in_hdr->priv.get.vert_skip = 0; return; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.