This is rle_getraw.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. * * Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire * to have all "void" functions so declared. */ /* * rle_getraw.c - * * Author: Spencer W. Thomas * Computer Science Dept. * University of Utah * Date: Mon Nov 10 1986 * Copyright (c) 1986, University of Utah */ #ifndef lint static char rcs_ident[] = "$Id: rle_getraw.c,v 3.0 90/08/03 15:20:41 spencer Exp $"; #endif #include <stdio.h> #include <rle.h> #include <rle_raw.h> #ifdef USE_STDLIB_H #include <stdlib.h> #else #ifndef VOID_STAR extern char * malloc(); #else extern void *malloc(); #endif extern void free(); #endif /* USE_STDLIB_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. */ /***************************************************************** * TAG( rle_getraw ) * * Get a raw scanline from the input file. * Inputs: * the_hdr: rle_hdr structure containing information about * the input file. * Outputs: * scanraw: an array of pointers to the individual color * scanlines. Scanraw is assumed to have * the_hdr->ncolors pointers to arrays of rle_op, * each of which with enough elements, at least * 1 + (the_hdr->xmax - the_hdr->xmin) / 3. * nraw: an array of integers giving the number of rle_ops for * each color channel. * Returns the current scanline number. Returns 32768 at EOF. * Assumptions: * rle_get_setup has already been called. * Algorithm: * Read input until a vertical skip is encountered, * decoding the instructions into the scanraw array. * Vertical skips that separate scanlines with no data do not * cause a return. In other words, the only reason for returning * with an empty scanline is end of file. * * When the scan_y reaches or exceeds the ymax, the rest of the * input image is skipped. This avoids problems with malformed * input files. */ unsigned int rle_getraw( the_hdr, scanraw, nraw ) rle_hdr *the_hdr; rle_op *scanraw[]; int nraw[]; { register int channel; register rle_op * rawp = NULL; FILE *infile = the_hdr->rle_file; char inst[2]; int scan_x = the_hdr->xmin; register int was_data; short word, long_data, nc, been_some = 0; /* Add in vertical skip from last scanline */ if ( the_hdr->priv.get.vert_skip > 0 ) the_hdr->priv.get.scan_y += the_hdr->priv.get.vert_skip; /* Set run lengths to 0 */ for ( channel = (the_hdr->alpha ? -1 : 0); channel < the_hdr->ncolors; channel++ ) if ( RLE_BIT( *the_hdr, channel ) ) nraw[channel] = 0; channel = 0; if ( the_hdr->priv.get.is_eof ) return 32768; /* too big for 16 bits, signal EOF */ /* Otherwise, read and interpret instructions until a skipLines * instruction is encountered. */ for (was_data = 0;;) { inst[0] = getc( infile ); inst[1] = getc( infile ); if ( feof(infile) ) { the_hdr->priv.get.is_eof = 1; break; /* <--- one of the exits */ } switch( OPCODE(inst) ) { case RSkipLinesOp: was_data = 1; if ( LONGP(inst) ) { VAXSHORT( the_hdr->priv.get.vert_skip, infile ); } else the_hdr->priv.get.vert_skip = DATUM(inst); break; /* need to break for() here, too */ case RSetColorOp: was_data = 1; channel = DATUM(inst); /* select color channel */ if ( channel == 255 ) channel = -1; scan_x = the_hdr->xmin; if ( RLE_BIT( *the_hdr, channel ) ) rawp = scanraw[channel]; else rawp = NULL; break; case RSkipPixelsOp: was_data = 1; if ( LONGP(inst) ) { VAXSHORT( long_data, infile ); scan_x += long_data; } else { scan_x += DATUM(inst); } break; case RByteDataOp: was_data = 1; if ( LONGP(inst) ) { VAXSHORT( nc, infile ); } else nc = DATUM(inst); nc++; if ( rawp != NULL ) { rawp->opcode = RByteDataOp; rawp->xloc = scan_x; rawp->length = nc; rawp->u.pixels = (rle_pixel *)malloc( (unsigned)nc ); fread( (char *)rawp->u.pixels, 1, nc, infile ); if ( nc & 1 ) (void)getc( infile ); /* throw away odd byte */ rawp++; nraw[channel]++; } else if ( the_hdr->priv.get.is_seek ) fseek( infile, ((nc + 1) / 2) * 2, 1 ); else { register int ii; for ( ii = ((nc + 1) / 2) * 2; ii > 0; ii-- ) (void) getc( infile ); /* discard it */ } scan_x += nc; been_some = 1; break; case RRunDataOp: was_data = 1; if ( LONGP(inst) ) { VAXSHORT( nc, infile ); } else nc = DATUM(inst); nc++; VAXSHORT( word, infile ); if ( rawp != NULL ) { rawp->opcode = RRunDataOp; rawp->xloc = scan_x; rawp->length = nc; rawp->u.run_val = word; rawp++; nraw[channel]++; } scan_x += nc; been_some = 1; break; case REOFOp: the_hdr->priv.get.is_eof = 1; break; default: fprintf( stderr, "rle_getraw: Unrecognized opcode: %d\n", OPCODE(inst) ); exit(1); } if ( OPCODE(inst) == REOFOp ) break; /* <--- the other loop exit */ if ( OPCODE(inst) == RSkipLinesOp ) { if ( been_some ) break; /* <--- the other loop exit */ else /* No data on that scanline, so move up to this scanline */ the_hdr->priv.get.scan_y += the_hdr->priv.get.vert_skip; } } /* If at top of image, skip any remaining. */ if ( the_hdr->priv.get.scan_y >= the_hdr->ymax ) { int y = the_hdr->priv.get.scan_y; while ( rle_getskip( the_hdr ) != 32768 ) ; return y; } /* Return current Y value */ return (was_data == 0) ? 32768 : the_hdr->priv.get.scan_y; } /***************************************************************** * TAG( rle_freeraw ) * * Free all the pixel arrays in the raw scan struct. * Inputs: * the_hdr: Header struct corresponding to this RLE data. * scanraw: Array of pointers to array of rle_op, as above. * nraw: Array of lengths (as above) * Outputs: * Frees the areas pointed to by the pixels elements of any * RByteDataOp type rle_op structs. * Assumptions: * [None] * Algorithm: * [None] */ void rle_freeraw( the_hdr, scanraw, nraw ) rle_hdr * the_hdr; int nraw[]; rle_op *scanraw[] ; { int c, i; register rle_op * raw_p; for ( c = -the_hdr->alpha; c < the_hdr->ncolors; c++ ) if ( RLE_BIT( *the_hdr, c ) ) for ( i = nraw[c], raw_p = scanraw[c]; i > 0; i--, raw_p++ ) if ( raw_p->opcode == RByteDataOp ) free( raw_p->u.pixels ); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.