This is rlesplice.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. */ /* rlesplice.c - Splice two RLE files together horizontally or vertically. * Pad smaller dimensioned image with its background color or * black. * * Author: Martin R. Friedmann (martin@media-lab.media.mit.edu) * Vision and Modeling Group * Massachusetts Institute of Technology * Date: Mon Apr 23 1990 (The Apocalypse) * Copyright (c) 1990, Martin R. Friedmann */ #include <stdio.h> #include <rle.h> #ifdef USE_STDLIB_H #include <stdlib.h> #endif #define MALLOC_ERR {fprintf(stderr, "%s: ran out of heap space\n", \ cmd_name( argv ));exit(-2);} #define VERT_FLAG 0x01 /* Command line flags */ #define HORIZ_FLAG 0x02 /* must match appearance in scanargs */ #define FOO_FLAG 0x04 #define Max(x, y) (((x) > (y)) ? (x) : (y) ) #define Min(x, y) (((x) < (y)) ? (x) : (y) ) static void bfill(); char *progname = NULL; int compatible_hdr(hdr_1, hdr_2) rle_hdr *hdr_1, *hdr_2; { #define Check(thing,printthing) \ if (hdr_1->thing != hdr_2->thing) \ { \ fprintf( stderr, "%s: %s does not match\n", progname, printthing); \ return 0; \ } Check(ncolors, "Number of color channels"); Check(alpha, "Existance of alpha channel"); Check(ncmap, "Number of colormap channels"); Check(cmaplen, "Colormap length"); return 1; #undef Check } void rle_row_clear( the_hdr, scanline ) rle_hdr * the_hdr; rle_pixel *scanline[]; { int nc; rle_pixel bg_color[255]; if ( the_hdr->alpha && RLE_BIT( *the_hdr, -1 ) ) bfill( (char *)scanline[-1], the_hdr->xmax + 1, 0 ); /* Clear to background if specified */ for ( nc = 0; nc < the_hdr->ncolors; nc++ ) { bg_color[nc] = (the_hdr->background == 2 ) ? the_hdr->bg_color[nc] : 0; if ( RLE_BIT( *the_hdr, nc ) ) bfill( (char *)scanline[nc], the_hdr->xmax+1, bg_color[nc] ); } } void main(argc, argv) int argc; char *argv[]; { char *infname1 = NULL, *outfname = NULL; char *infname2 = NULL; int oflag = 0, hvflag = 0, cflag = 0; int rle_cnt = 0; FILE *outfile = stdout; int j; int new_xlen, new_ylen; int rle_err1, rle_err2 = 0; rle_hdr in_hdr1, in_hdr2, out_hdr; int xmin, ymin, width1, width2, height1, height2; progname = cmd_name( argv ); if ( scanargs( argc, argv, "% hv!- c%- o%-outfile!s infile1!s infile2!s", &hvflag, &cflag, &oflag, &outfname, &infname1, &infname2 ) == 0 ) exit( 1 ); in_hdr1.rle_file = rle_open_f( progname, infname1, "r" ); in_hdr2.rle_file = rle_open_f( progname, infname2, "r" ); /* Both standard input? */ if ( in_hdr1.rle_file == in_hdr2.rle_file ) { fprintf( stderr, "Both files can't be on standard input.\n" ); exit( -1 ); } while ((rle_err1 = rle_get_setup( &in_hdr1 )) == RLE_SUCCESS && (rle_err2 = rle_get_setup( &in_hdr2 )) == RLE_SUCCESS ) { rle_pixel **rows1, **rows2, **rowsout; rle_pixel *ptr1, *ptr2, *ptrout; int start_scan1, start_scan2, pad1, pad2; int chan; if ( rle_cnt == 0 ) outfile = rle_open_f( progname, outfname, "w" ); rle_cnt++; /* Count images in this file. */ if (!compatible_hdr(&in_hdr1, &in_hdr2)) { fprintf(stderr, "%s: Non-compatible rle files: %s and %s\n", progname, infname1, infname2); exit(1); } out_hdr = in_hdr1; rle_addhist( argv, &in_hdr1, &out_hdr ); /* preserve xmin and ymin from in_hdr1 */ xmin = in_hdr1.xmin; ymin = in_hdr1.ymin; width1 = in_hdr1.xmax - in_hdr1.xmin + 1; width2 = in_hdr2.xmax - in_hdr2.xmin + 1; height1 = in_hdr1.ymax - in_hdr1.ymin + 1; height2 = in_hdr2.ymax - in_hdr2.ymin + 1; if (hvflag == VERT_FLAG) { new_xlen = Max( width1, width2 ); new_ylen = height1 + height2; } else { new_xlen = width1 + width2; new_ylen = Max( height1, height2 ); } out_hdr.xmin = xmin; out_hdr.ymin = ymin; out_hdr.xmax = xmin + new_xlen - 1; out_hdr.ymax = ymin + new_ylen - 1; out_hdr.rle_file = outfile; rle_put_setup( &out_hdr ); /* Oink. */ if (rle_row_alloc( &in_hdr1, &rows1 )) MALLOC_ERR; if (rle_row_alloc( &in_hdr2, &rows2 )) MALLOC_ERR; if (rle_row_alloc( &out_hdr, &rowsout )) MALLOC_ERR; rle_row_clear( &in_hdr1, rows1 ); rle_row_clear( &in_hdr2, rows2 ); rle_row_clear( &out_hdr, rowsout ); if ( hvflag == HORIZ_FLAG ) { int diff = height1 - height2 ; start_scan1 = start_scan2 = pad1 = pad2 = 0; if ( height1 < height2 ) start_scan1 = (cflag) ? -diff/2 : new_ylen - height1; else if ( height2 < height1 ) start_scan2 = (cflag) ? diff/2 : new_ylen - height2; } else { /* upside down remember */ start_scan2 = pad1 = pad2 = 0; start_scan1 = height2; if ( width1 < width2 ) pad1 = (cflag) ? (width2 - width1)/2 : 0; else if (width2 < width1 ) pad2 = (cflag) ? (width1 - width2)/2 : 0; } for ( j = 0; j < new_ylen; j++ ) { if ( start_scan1 <= j && hvflag == VERT_FLAG ) { start_scan2 = new_ylen + 1; /* never again */ rle_row_clear( &out_hdr, rowsout ); } if ( start_scan1 <= j ) rle_getrow(&in_hdr1, rows1 ); if ( start_scan2 <= j ) rle_getrow(&in_hdr2, rows2 ); for (chan = RLE_ALPHA; chan < in_hdr1.ncolors; chan++) { if ((chan == RLE_ALPHA) && (!in_hdr1.alpha)) continue; ptr1 = &(rows1[chan][in_hdr1.xmin]); ptr2 = &(rows2[chan][in_hdr2.xmin]); ptrout = rowsout[chan]; if ( start_scan1 <= j ) bcopy( ptr1, ptrout + pad1, width1 ); if ( start_scan2 <= j ) bcopy( ptr2,((char *)ptrout) + pad2 + ((hvflag == VERT_FLAG) ? 0 : width1), width2 ); } rle_putrow( rowsout, new_xlen, &out_hdr ); } rle_puteof( &out_hdr ); rle_row_free( &in_hdr1, rows1 ); rle_row_free( &in_hdr2, rows2 ); rle_row_free( &out_hdr, rowsout ); } if ( rle_cnt == 0 || (rle_err1 != RLE_EOF && rle_err1 != RLE_EMPTY && rle_err2 != RLE_EOF && rle_err2 != RLE_EMPTY ) ) { if (rle_err1 != RLE_SUCCESS) rle_get_error( rle_err1, progname, infname1 ); if (rle_err2 != RLE_SUCCESS) rle_get_error( rle_err2, progname, infname2 ); } exit( 0 ); } /* Fill buffer at s with n copies of character c. N must be <= 65535*/ /* ARGSUSED */ static void bfill( s, n, c ) char *s; int n, c; { #ifdef vax asm(" movc5 $0,*4(ap),12(ap),8(ap),*4(ap)"); #else while ( n-- > 0 ) *s++ = c; #endif }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.