/* * 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. */ /* * rlepatch.c - Patch images over a larger image. * * Author: John W. Peterson * Computer Science Dept. * University of Utah * Date: Sun Nov 29 1987 * Copyright (c) 1987, University of Utah * * This was a quick hack. It should be changed to use the "raw" * routines someday - this would run MUCH faster for sparse patches. */ #include #include "rle.h" #define IN_WINDOW(y,wind) ((y >= wind.ymin) && (y <= wind.ymax)) void main( argc, argv ) int argc; char **argv; { rle_hdr im_hdr, out_hdr; rle_hdr *patch_hdr; CONST_DECL char *imfilename = NULL, *outfilename = NULL; CONST_DECL char **patchnames; FILE *outfile = stdout; rle_pixel ** im_rows, **patch_rows, ** outrows; int stdin_used = 0; int patches = 0, oflag = 0, i, y, c, xlen, width; int rle_cnt; im_hdr = *rle_hdr_init( NULL ); out_hdr = *rle_hdr_init( NULL ); if (! scanargs( argc, argv, "% o%-outfile!s infile!s patchfiles%*s", &oflag, &outfilename, &imfilename, &patches, &patchnames )) exit( -1 ); patch_hdr = (rle_hdr *) malloc( sizeof( rle_hdr ) * patches ); RLE_CHECK_ALLOC( cmd_name( argv ), patch_hdr, "patch headers" ); /* Setup the main image data structures. */ im_hdr.rle_file = rle_open_f( cmd_name( argv ), imfilename, "r" ); if ( im_hdr.rle_file == stdin ) stdin_used++; rle_names( &im_hdr, cmd_name( argv ), imfilename, 0 ); rle_names( &out_hdr, im_hdr.cmd, outfilename, 0 ); for( i = 0; i < patches; i++ ) { patch_hdr[i] = *rle_hdr_init( NULL ); patch_hdr[i].rle_file = rle_open_f( cmd_name( argv ), patchnames[i], "r" ); rle_names( &patch_hdr[i], im_hdr.cmd, patchnames[i], 0 ); if ( patch_hdr[i].rle_file == stdin ) { if ( stdin_used ) { fprintf(stderr, "%s: Only use stdin (-) once.\n", cmd_name( argv )); exit(-1); } stdin_used++; } } for ( rle_cnt = 0; rle_get_setup( &im_hdr ) == RLE_SUCCESS; rle_cnt++ ) { /* Get the patch files set up */ for( i = 0; i < patches; i++ ) { rle_get_setup_ok( &patch_hdr[i], patch_hdr[i].cmd, patch_hdr[i].file_name ); /* Sanity checks. */ if ((patch_hdr[i].xmin < im_hdr.xmin) || (patch_hdr[i].xmax > im_hdr.xmax) || (patch_hdr[i].ymin < im_hdr.ymin) || (patch_hdr[i].ymax > im_hdr.ymax)) { fprintf( stderr, "%s: file %s is outside %s\n", im_hdr.cmd, patch_hdr[i].file_name, im_hdr.file_name ); exit( -2 ); } if ((patch_hdr[i].ncolors != im_hdr.ncolors) || (patch_hdr[i].alpha != im_hdr.alpha)) { fprintf( stderr, "%s: file %s doesn't have the same channels as %s\n", im_hdr.cmd, patch_hdr[i].file_name, im_hdr.file_name ); exit(-2); } } if (rle_row_alloc( &im_hdr, &im_rows ) || rle_row_alloc( &im_hdr, &patch_rows )) RLE_CHECK_ALLOC( cmd_name( argv ), 0, "image and patch data" ); /* Setup output */ (void)rle_hdr_cp( &im_hdr, &out_hdr ); if ( rle_cnt == 0 ) outfile = rle_open_f( cmd_name( argv ), outfilename, "w" ); out_hdr.rle_file = outfile; rle_addhist( argv, &im_hdr, &out_hdr ); rle_put_setup( &out_hdr ); /* * Allocate pointers to the output rows. Note that rle_putrow * expects the pointers to start at xmin, instead of at zero * like rle_getrow (Weird Spencerism). */ outrows = (rle_pixel**) malloc( sizeof( rle_pixel** ) * (im_hdr.alpha + im_hdr.ncolors)); RLE_CHECK_ALLOC( cmd_name( argv ), outrows, "output image data" ); if (im_hdr.alpha) outrows++; /* Put alpha at -1 index */ xlen = out_hdr.xmax - out_hdr.xmin + 1; for( i = -im_hdr.alpha; i < im_hdr.ncolors; i++ ) outrows[i] = &(im_rows[i][im_hdr.xmin]); /* Process the images. */ for (y = im_hdr.ymin; y <= im_hdr.ymax; y++) { rle_getrow( &im_hdr, im_rows ); for (i = 0; i < patches; i++) { if (IN_WINDOW( y, patch_hdr[i])) { rle_getrow( &(patch_hdr[i]), patch_rows ); width = patch_hdr[i].xmax - patch_hdr[i].xmin + 1; for( c = -im_hdr.alpha; c < im_hdr.ncolors; c++) bcopy( &(patch_rows[c][patch_hdr[i].xmin]), &(im_rows[c][patch_hdr[i].xmin]), width ); } } rle_putrow( outrows, xlen, &out_hdr ); } rle_puteof( &out_hdr ); /* Release memory. */ rle_row_free( &im_hdr, im_rows ); rle_row_free( &im_hdr, patch_rows ); if ( im_hdr.alpha ) outrows--; free( outrows ); } exit( 0 ); }