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.