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.