This is mergechan.c in view mode; [Download] [Up]
/* * mergechan.c - Merge channels from multiple RLE images * * Author: John W. Peterson * Computer Science Dept. * University of Utah * Date: Mon Nov 9 1987 * Copyright (c) 1987, University of Utah * * Warning: this code does not intelligently deal with color maps! * */ #include <stdio.h> #include "rle.h" #include <rle_raw.h> #ifdef USE_STDLIB_H #include <stdlib.h> #else #ifdef VOID_STAR extern void *malloc(); #else extern char *malloc(); #endif extern void free(); #endif /* USE_STDLIB_H */ #define CHECK_MALLOC( ptr ) \ { if (! (ptr)) {fprintf( stderr, "%s: Malloc failed\n", cmd_name( argv ) ); \ exit(-2);}} #define MIN(i,j) ( (i) < (j) ? (i) : (j) ) #define RLE_END 32768 /* This should be in rle.h */ void main( argc, argv ) int argc; char ** argv; { int nfiles; rle_hdr * in_hdr; rle_hdr out_hdr; int alpha_flag = 0, oflag = 0; rle_op *** in_rows; /* A Carl Sagan pointer. */ int ** in_counts; /* nraw */ rle_op ** out_rows; int * out_count; int * skips; CONST_DECL char **filenames, *out_fname = NULL; FILE *outfile = stdout; int minskip = 0, y; register int i; int rle_cnt, rle_err, stdin_used = -1; if (! scanargs( argc, argv, "% a%- o%-outfile!s files%*s", &alpha_flag, &oflag, &out_fname, &nfiles, &filenames )) exit( -1 ); if (alpha_flag) alpha_flag = 1; /* So indexing's right. */ in_hdr = (rle_hdr *) malloc( sizeof( rle_hdr ) * nfiles ); in_rows = (rle_op ***) malloc( sizeof( rle_op ** ) * nfiles ); CHECK_MALLOC( in_rows ); in_counts = (int **) malloc( sizeof( int * ) * nfiles ); CHECK_MALLOC( in_counts ); skips = (int *) malloc( sizeof( int ) * nfiles ); CHECK_MALLOC( skips ); out_rows = (rle_op **) malloc( sizeof( rle_op * ) * nfiles ); CHECK_MALLOC( out_rows ); out_count = (int *) malloc( sizeof( int ) * nfiles ); CHECK_MALLOC( out_count ); /* Open all the files, and check consistancy */ for (i = 0; i < nfiles; i++) { in_hdr[i].rle_file = rle_open_f("mergechan", filenames[i], "r"); if ( in_hdr[i].rle_file == stdin ) if ( stdin_used < 0 ) { filenames[i] = "Standard Input"; stdin_used = i; } else { fprintf( stderr, "%s: Images %d and %d are both from the standard input\n", stdin_used, i ); exit( -1 ); } } /* Note: the only way out of this loop is via one of the two exit * calls below. */ for ( rle_cnt = 0; ; rle_cnt++ ) { for (i = 0; i < nfiles; i++) { /* Check for an error. EOF or EMPTY is ok if at least one image * has been read. Otherwise, print an error message. EOF * or EMPTY after first image means end of input. */ if ( (rle_err = rle_get_setup( &in_hdr[i])) != RLE_SUCCESS ) if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) ) { rle_get_error( rle_err, cmd_name( argv ), filenames[i] ); exit( 1 ); } else if ( rle_err == RLE_EOF || rle_err == RLE_EMPTY ) exit( 0 ); /* Check that the channel's really there */ if (((in_hdr[i].ncolors-1) < (i-alpha_flag)) || (! RLE_BIT( in_hdr[i], i-alpha_flag ))) { fprintf(stderr, "mergechan: channel %d not in file %s\n", i, filenames[i] ); exit( -2 ); } /* Check to make sure all images have the same size */ if (i > 0) { if (! ((in_hdr[0].xmin == in_hdr[i].xmin) && (in_hdr[0].xmax == in_hdr[i].xmax) && (in_hdr[0].ymin == in_hdr[i].ymin) && (in_hdr[0].ymax == in_hdr[i].ymax)) ) { fprintf(stderr, "mergechan: image %s is not the same size as image %s\n", filenames[i], filenames[0] ); exit( -2 ); } } if( rle_raw_alloc( &(in_hdr[i]), &(in_rows[i]), &(in_counts[i]) )) { fprintf( stderr, "mergechan: can't allocate raw storage\n" ); exit(-2); } } /* Setup output stuff */ out_hdr = in_hdr[0]; rle_addhist( argv, &in_hdr[0], &out_hdr ); if ( rle_cnt == 0 ) outfile = rle_open_f("mergechan", out_fname, "w"); out_hdr.rle_file = outfile; out_hdr.ncolors = nfiles - alpha_flag; out_hdr.alpha = alpha_flag; /* Enable all output channels. */ for (i = -alpha_flag; i < out_hdr.ncolors; i++) RLE_SET_BIT( out_hdr, i ); rle_put_setup( &out_hdr ); if (alpha_flag) /* So indexing's right (alpha == -1) */ { in_hdr++; in_rows++; in_counts++; out_rows++; out_count++; skips++; } /* Initialize counters */ for (i = -alpha_flag; i < out_hdr.ncolors; i++) { skips[i] = 0; out_rows[i] = in_rows[i][i]; } y = out_hdr.ymin - 1; /* -1 'cuz we haven't read data yet */ /* * Do the actual work. Since rle_getraw may "skip" several lines * ahead, we need to keep track of the Y position of each channel * independently with skips[]. The output moves ahead by the * minimum of these skip values (minskip). */ while (1) /* Stops at EOF on all files */ { for (i = -alpha_flag; i < out_hdr.ncolors; i++) { if (! skips[i]) { skips[i] = rle_getraw( &(in_hdr[i]), in_rows[i], in_counts[i] ); if (skips[i] != RLE_END) skips[i] -= y; /* Store delta to next data */ } /* Find smallest skip distance until a channel has data again */ if (i == -alpha_flag) minskip = skips[i]; else minskip = MIN( skips[i], minskip ); } if (minskip == RLE_END) break; /* Hit the end of all input files */ if (minskip > 1) rle_skiprow( &out_hdr, minskip-1 ); y += minskip; for (i = -alpha_flag; i < out_hdr.ncolors; i++) { if (skips[i] != RLE_END) skips[i] -= minskip; if (skips[i] == 0) /* Has data to go out */ { out_count[i] = in_counts[i][i]; } else { out_count[i] = 0; } } rle_putraw( out_rows, out_count, &out_hdr ); for (i = -alpha_flag; i < out_hdr.ncolors; i++) { if (skips[i] == 0) /* Data is written, so free the raws */ { rle_freeraw( &(in_hdr[i]), in_rows[i], in_counts[i] ); } } } rle_puteof( &out_hdr ); /* Free storage. */ if (alpha_flag) { in_hdr--; in_rows--; in_counts--; out_rows--; out_count--; skips--; } for ( i = 0; i < nfiles; i++ ) rle_raw_free( &in_hdr[i], in_rows[i], in_counts[i] ); } /* NOTREACHED */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.