This is pyrmask.c in view mode; [Download] [Up]
/*
* pyrhalf.c - Create bandpass pyramid for pyramid operations.
*
* Author: Rod Bogart
* Computer Science Dept.
* University of Utah
* Date: Wed Oct 15 1986
* Copyright (c) 1986, University of Utah
*
*/
#ifndef lint
static char rcs_ident[] = "$Header: /usr/users/spencer/src/urt/tools/RCS/pyrmask.c,v 3.0 90/08/03 15:22:16 spencer Exp $";
#endif
#include <stdio.h>
#include "rle.h"
#include "pyramid.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 */
int rle_to_pyramids();
void alloc_pyramid(), copy_mask_bands(), rebuild_image(), dump_pyramid();
void copy_half_bands();
void
main(argc, argv)
int argc;
char *argv[];
{
char * leftname = NULL, * rightname = NULL, * outfname = NULL;
char * maskname = NULL, * errname;
FILE * leftfile, * rightfile, *maskfile, * outfile;
int oflag = 0, lflag = 0;
int i, j, k;
int rle_cnt, rle_err;
float *maskmult;
float *mask_mult_table;
float *mask;
int level, levels = 0;
rle_pixel *imgcorner;
pyramid leftgausspyr, leftbandpyr;
pyramid rightgausspyr, rightbandpyr;
pyramid maskgausspyr;
pyramid splitpyr;
/*
* "Left" and "right" are historical relics from a program that
* joined two images at the middle. Left == inside mask; right == outside.
*/
rle_hdr left_hdr;
rle_hdr right_hdr;
rle_hdr mask_hdr;
if ( scanargs( argc, argv,
"% l%-levels!d o%-outfile!s inmask!s outmask!s maskfile!s",
&lflag, &levels,
&oflag, &outfname, &leftname, &rightname, &maskname ) == 0 )
exit( 1 );
leftfile = rle_open_f( cmd_name( argv ), leftname, "r" );
rightfile = rle_open_f( cmd_name( argv ), rightname, "r" );
maskfile = rle_open_f( cmd_name( argv ), maskname, "r" );
outfile = rle_open_f( cmd_name( argv ), outfname, "w" );
/* actual mask is always 5x5 */
mask = gauss_mask(5);
/* initialize mask_mult_table */
mask_mult_table = (float *) malloc(sizeof(float) * 5 * 5 * 256);
for (i=0; i < 5; i++)
{
maskmult = &(mask_mult_table[(i*5) << 8]);
for (j=0; j < 5; j++)
{
for (k=0;k < 256; k++)
maskmult[ k ] = (float) k * mask[i*5+j];
maskmult += 256;
}
}
for ( rle_cnt = 0; ; rle_cnt++ )
{
if ( (rle_err = rle_to_pyramids( leftfile, &leftgausspyr, &leftbandpyr,
&left_hdr, levels, mask_mult_table ))
!= RLE_SUCCESS )
{
errname = leftname;
break;
}
if ( (rle_err = rle_to_pyramids( rightfile, &rightgausspyr,
&rightbandpyr, &right_hdr,
levels, mask_mult_table ))
!= RLE_SUCCESS )
{
errname = rightname;
break;
}
if ( (rle_err = rle_to_pyramids( maskfile, &maskgausspyr, 0,
&mask_hdr, levels, mask_mult_table ))
!= RLE_SUCCESS )
{
errname = maskname;
break;
}
if (leftgausspyr.nchan != rightgausspyr.nchan)
{
fprintf(stderr,
"%s: Left and right images must have same number of channels\n",
cmd_name( argv ));
exit(-2);
}
if ((leftgausspyr.xlen[0] != rightgausspyr.xlen[0]) ||
(leftgausspyr.ylen[0] != rightgausspyr.ylen[0]))
{
fprintf(stderr,
"%s: Left and right images must have same dimensions\n",
cmd_name( argv ));
exit(-2);
}
if (leftgausspyr.nchan != maskgausspyr.nchan)
{
fprintf(stderr,
"%s: Currently, mask image must have a mask per input channel\n",
cmd_name( argv ));
exit(-2);
}
if ((leftgausspyr.xlen[0] != maskgausspyr.xlen[0]) ||
(leftgausspyr.ylen[0] != maskgausspyr.ylen[0]))
{
fprintf(stderr,
"%s: Mask image must have same dimensions as input images\n",
cmd_name( argv ));
exit(-2);
}
splitpyr.nchan = leftbandpyr.nchan;
splitpyr.levels = leftbandpyr.levels;
splitpyr.corners = (rle_pixel **) malloc( splitpyr.levels
* sizeof( rle_pixel *) );
splitpyr.xlen = (int *) malloc( splitpyr.levels * sizeof( int ) );
splitpyr.ylen = (int *) malloc( splitpyr.levels * sizeof( int ) );
if ( (!splitpyr.corners) or (!splitpyr.xlen) or (!splitpyr.ylen) )
{
fprintf(stderr,
"%s: could not allocate space for split pyramid\n",
cmd_name( argv ));
exit(-2);
}
splitpyr.xlen[0] = leftbandpyr.xlen[0];
splitpyr.ylen[0] = leftbandpyr.ylen[0];
alloc_pyramid(&splitpyr);
for(level = splitpyr.levels - 1; level >= 0; level--)
{
copy_mask_bands(level,&leftbandpyr,&rightbandpyr,
&splitpyr,&maskgausspyr);
}
/****************************************************
* Reconstruct the image from the band pyramid
****************************************************/
rebuild_image(&imgcorner,&splitpyr,mask_mult_table);
rle_addhist( argv, &left_hdr, &left_hdr );
dump_pyramid(outfile,1,&imgcorner,splitpyr.xlen[0],splitpyr.ylen[0],
splitpyr.nchan - 1,left_hdr);
}
/* Check for an error. EOF or EMPTY is ok if at least one image
* has been read. Otherwise, print an error message.
*/
if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
rle_get_error( rle_err, cmd_name( argv ), errname );
exit(0);
}
void
copy_half_bands(level,leftbandpyr, rightbandpyr, splitbandpyr)
int level;
pyramid * leftbandpyr, * rightbandpyr, *splitbandpyr;
{
int xsize, ysize, x, y, chan, xlinewidth, nchan;
rle_pixel *leftbase, *leftrastptr, *leftpxl, *leftsign;
rle_pixel *rightbase, *rightrastptr, *rightpxl, *rightsign;
rle_pixel *outbase, *outrastptr, *outpxl, *outsign;
float tval;
int rightval, leftval, outval;
leftbase = leftbandpyr->corners[level];
rightbase = rightbandpyr->corners[level];
outbase = splitbandpyr->corners[level];
xsize = leftbandpyr->xlen[level];
ysize = leftbandpyr->ylen[level];
nchan = leftbandpyr->nchan - 1;
splitbandpyr->xlen[level] = xsize;
splitbandpyr->ylen[level] = ysize;
xlinewidth = xsize + MASKSIZE - 1;
fprintf(stderr,"Copying half of level %d, size %d\n",level,xsize);
for (y = 0; y < ysize; y++)
{
leftrastptr = &(leftbase[MASKBELOW + (y+MASKBELOW) *
xlinewidth * (nchan+1)]);
rightrastptr = &(rightbase[MASKBELOW + (y+MASKBELOW) *
xlinewidth * (nchan+1)]);
outrastptr = &(outbase[MASKBELOW + (y+MASKBELOW) *
xlinewidth * (nchan+1)]);
outsign = &(outrastptr[nchan * xlinewidth]);
for(x=0; x < xsize; x++)
{
*outsign = 0;
}
for (chan = 0; chan < nchan; chan++)
{
leftpxl = &(leftrastptr[chan * xlinewidth]);
leftsign = &(leftrastptr[nchan * xlinewidth]);
rightpxl = &(rightrastptr[chan * xlinewidth]);
rightsign = &(rightrastptr[nchan * xlinewidth]);
outpxl = &(outrastptr[chan * xlinewidth]);
outsign = &(outrastptr[nchan * xlinewidth]);
for(x=0; x < xsize; x++)
{
/* should do some mask magic here */
if (x <= (15 * xsize / 32))
{
*outpxl = (*leftpxl);
if ((1 << chan) & (*leftsign))
*outsign |= (1 << chan);
}
else if (x >= (17 * xsize / 32))
{
*outpxl = (*rightpxl);
if ((1 << chan) & (*rightsign))
*outsign |= (1 << chan);
}
else
{
tval = ((float) x - (15.0 * (float) xsize / 32.0)) /
((float) xsize / 16.0);
leftval = (int) (*leftpxl) *
(((1 << chan) & (*leftsign)) ? -1 : 1);
rightval = (int) (*rightpxl) *
(((1 << chan) & (*rightsign)) ? -1 : 1);
outval = (int) (tval * (float) rightval +
(1.0 - tval) * (float) leftval);
if (outval < 0)
{
*outpxl = (rle_pixel) (-outval);
*outsign |= (1 << chan);
}
else
*outpxl = (rle_pixel) (outval);
}
leftpxl++;
rightpxl++;
outpxl++;
leftsign++;
rightsign++;
outsign++;
}
}
}
}
void
copy_mask_bands(level,leftbandpyr, rightbandpyr, splitbandpyr, maskgausspyr)
int level;
pyramid * leftbandpyr, * rightbandpyr, *splitbandpyr, *maskgausspyr;
{
int xsize, ysize, x, y, chan, xlinewidth, nchan;
rle_pixel *leftbase, *leftrastptr, *leftpxl, *leftsign;
rle_pixel *rightbase, *rightrastptr, *rightpxl, *rightsign;
rle_pixel *outbase, *outrastptr, *outpxl, *outsign;
rle_pixel *maskbase, *maskrastptr, *maskpxl;
float tval;
int rightval, leftval, outval;
leftbase = leftbandpyr->corners[level];
rightbase = rightbandpyr->corners[level];
outbase = splitbandpyr->corners[level];
maskbase = maskgausspyr->corners[level];
xsize = leftbandpyr->xlen[level];
ysize = leftbandpyr->ylen[level];
nchan = leftbandpyr->nchan - 1;
splitbandpyr->xlen[level] = xsize;
splitbandpyr->ylen[level] = ysize;
xlinewidth = xsize + MASKSIZE - 1;
/* fprintf(stderr,"Masking level %d, size %d\n",level,xsize); */
for (y = 0; y < ysize; y++)
{
leftrastptr = &(leftbase[MASKBELOW + (y+MASKBELOW) *
xlinewidth * (nchan+1)]);
rightrastptr = &(rightbase[MASKBELOW + (y+MASKBELOW) *
xlinewidth * (nchan+1)]);
outrastptr = &(outbase[MASKBELOW + (y+MASKBELOW) *
xlinewidth * (nchan+1)]);
maskrastptr = &(maskbase[MASKBELOW + (y+MASKBELOW) *
xlinewidth * nchan]);
outsign = &(outrastptr[nchan * xlinewidth]);
for(x=0; x < xsize; x++)
{
*outsign = 0;
}
for (chan = 0; chan < nchan; chan++)
{
leftpxl = &(leftrastptr[chan * xlinewidth]);
leftsign = &(leftrastptr[nchan * xlinewidth]);
rightpxl = &(rightrastptr[chan * xlinewidth]);
rightsign = &(rightrastptr[nchan * xlinewidth]);
outpxl = &(outrastptr[chan * xlinewidth]);
outsign = &(outrastptr[nchan * xlinewidth]);
maskpxl = &(maskrastptr[chan * xlinewidth]);
for(x=0; x < xsize; x++)
{
/* should do some mask magic here */
if (*maskpxl == 255) /* full coverage means left image */
{
*outpxl = (*leftpxl);
if ((1 << chan) & (*leftsign))
*outsign |= (1 << chan);
}
else if (*maskpxl == 0) /* no coverage means right image */
{
*outpxl = (*rightpxl);
if ((1 << chan) & (*rightsign))
*outsign |= (1 << chan);
}
else
{
tval = ((float) (*maskpxl)) / 255.0;
leftval = (int) (*leftpxl) *
(((1 << chan) & (*leftsign)) ? -1 : 1);
rightval = (int) (*rightpxl) *
(((1 << chan) & (*rightsign)) ? -1 : 1);
outval = (int) (tval * (float) leftval +
(1.0 - tval) * (float) rightval);
if (outval < 0)
{
*outpxl = (rle_pixel) (-outval);
*outsign |= (1 << chan);
}
else
*outpxl = (rle_pixel) (outval);
}
leftpxl++;
rightpxl++;
outpxl++;
maskpxl++;
leftsign++;
rightsign++;
outsign++;
}
}
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.