Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
pyrmask.c
Go to the documentation of this file.
1 /*
2  * pyrhalf.c - Create bandpass pyramid for pyramid operations.
3  *
4  * Author: Rod Bogart
5  * Computer Science Dept.
6  * University of Utah
7  * Date: Wed Oct 15 1986
8  * Copyright (c) 1986, University of Utah
9  *
10  */
11 #ifndef lint
12 static char rcs_ident[] = "$Header: /software/dmsv/sun4/sunos/SWT-BACKUP/spencer/src/urt/tools/tools/RCS/pyrmask.c,v 3.0.1.2 1992/01/23 16:26:22 spencer Exp $";
13 #endif
14 
15 #include <stdio.h>
16 #include "rle.h"
17 #include "pyramid.h"
18 
19 int rle_to_pyramids();
21 void copy_half_bands();
22 
23 void
25 int argc;
26 char *argv[];
27 {
28  char * leftname = NULL, * rightname = NULL, * outfname = NULL;
29  char * maskname = NULL, * errname;
30  FILE * leftfile, * rightfile, *maskfile, * outfile;
31  int oflag = 0, lflag = 0;
32  int i, j, k;
33  int rle_cnt, rle_err;
34 
35  float *maskmult;
36  float *mask_mult_table;
37  float *mask;
38  int level, levels = 0;
39  rle_pixel *imgcorner;
40  pyramid leftgausspyr, leftbandpyr;
41  pyramid rightgausspyr, rightbandpyr;
42  pyramid maskgausspyr;
43  pyramid splitpyr;
44  /*
45  * "Left" and "right" are historical relics from a program that
46  * joined two images at the middle. Left == inside mask; right == outside.
47  */
48  rle_hdr left_hdr;
49  rle_hdr right_hdr;
50  rle_hdr mask_hdr;
51  rle_hdr out_hdr;
52 
53  left_hdr = *rle_hdr_init( NULL );
54  right_hdr = *rle_hdr_init( NULL );
55  mask_hdr = *rle_hdr_init( NULL );
56 
57  if ( scanargs( argc, argv,
58  "% l%-levels!d o%-outfile!s inmask!s outmask!s maskfile!s",
59  &lflag, &levels,
60  &oflag, &outfname, &leftname, &rightname, &maskname ) == 0 )
61  exit( 1 );
62 
63  leftfile = rle_open_f( cmd_name( argv ), leftname, "r" );
64  rightfile = rle_open_f( cmd_name( argv ), rightname, "r" );
65  maskfile = rle_open_f( cmd_name( argv ), maskname, "r" );
66 
67  outfile = rle_open_f( cmd_name( argv ), outfname, "w" );
68 
69  /* actual mask is always 5x5 */
70  mask = gauss_mask(5);
71 
72  /* initialize mask_mult_table */
73  mask_mult_table = (float *) malloc(sizeof(float) * 5 * 5 * 256);
74  RLE_CHECK_ALLOC( cmd_name( argv ), mask_mult_table, "mask" );
75  for (i=0; i < 5; i++)
76  {
77  maskmult = &(mask_mult_table[(i*5) << 8]);
78  for (j=0; j < 5; j++)
79  {
80  for (k=0;k < 256; k++)
81  maskmult[ k ] = (float) k * mask[i*5+j];
82  maskmult += 256;
83  }
84  }
85 
86  rle_names( &left_hdr, cmd_name( argv ), leftname, 0 );
87  rle_names( &right_hdr, cmd_name( argv ), rightname, 0 );
88  rle_names( &mask_hdr, cmd_name( argv ), maskname, 0 );
89  rle_names( &out_hdr, left_hdr.cmd, outfname, 0 );
90 
91  for ( rle_cnt = 0; ; rle_cnt++ )
92  {
93  if ( (rle_err = rle_to_pyramids( leftfile, &leftgausspyr, &leftbandpyr,
94  &left_hdr, levels, mask_mult_table ))
95  != RLE_SUCCESS )
96  {
97  errname = leftname;
98  break;
99  }
100 
101  if ( (rle_err = rle_to_pyramids( rightfile, &rightgausspyr,
102  &rightbandpyr, &right_hdr,
103  levels, mask_mult_table ))
104  != RLE_SUCCESS )
105  {
106  errname = rightname;
107  break;
108  }
109 
110  if ( (rle_err = rle_to_pyramids( maskfile, &maskgausspyr, 0,
111  &mask_hdr, levels, mask_mult_table ))
112  != RLE_SUCCESS )
113  {
114  errname = maskname;
115  break;
116  }
117 
118  if (leftgausspyr.nchan != rightgausspyr.nchan)
119  {
120  fprintf(stderr,
121  "%s: Left and right images must have same number of channels\n",
122  cmd_name( argv ));
123  exit(-2);
124  }
125  if ((leftgausspyr.xlen[0] != rightgausspyr.xlen[0]) ||
126  (leftgausspyr.ylen[0] != rightgausspyr.ylen[0]))
127  {
128  fprintf(stderr,
129  "%s: Left and right images must have same dimensions\n",
130  cmd_name( argv ));
131  exit(-2);
132  }
133  if (leftgausspyr.nchan != maskgausspyr.nchan)
134  {
135  fprintf(stderr,
136  "%s: Currently, mask image must have a mask per input channel\n",
137  cmd_name( argv ));
138  exit(-2);
139  }
140  if ((leftgausspyr.xlen[0] != maskgausspyr.xlen[0]) ||
141  (leftgausspyr.ylen[0] != maskgausspyr.ylen[0]))
142  {
143  fprintf(stderr,
144  "%s: Mask image must have same dimensions as input images\n",
145  cmd_name( argv ));
146  exit(-2);
147  }
148 
149  splitpyr.nchan = leftbandpyr.nchan;
150  splitpyr.levels = leftbandpyr.levels;
151  splitpyr.corners = (rle_pixel **) malloc( splitpyr.levels
152  * sizeof( rle_pixel *) );
153  splitpyr.xlen = (int *) malloc( splitpyr.levels * sizeof( int ) );
154  splitpyr.ylen = (int *) malloc( splitpyr.levels * sizeof( int ) );
156  splitpyr.corners && splitpyr.xlen && splitpyr.ylen,
157  "split pyramid" );
158 
159  splitpyr.xlen[0] = leftbandpyr.xlen[0];
160  splitpyr.ylen[0] = leftbandpyr.ylen[0];
161  alloc_pyramid(&splitpyr);
162 
163  for(level = splitpyr.levels - 1; level >= 0; level--)
164  {
165  copy_mask_bands(level,&leftbandpyr,&rightbandpyr,
166  &splitpyr,&maskgausspyr);
167  }
168  /****************************************************
169  * Reconstruct the image from the band pyramid
170  ****************************************************/
171  rebuild_image(&imgcorner,&splitpyr,mask_mult_table);
172 
173  rle_hdr_cp( &left_hdr, &out_hdr );
174  rle_addhist( argv, &left_hdr, &out_hdr );
175  dump_pyramid(outfile,1,&imgcorner,splitpyr.xlen[0],splitpyr.ylen[0],
176  splitpyr.nchan - 1,left_hdr);
177  }
178  /* Check for an error. EOF or EMPTY is ok if at least one image
179  * has been read. Otherwise, print an error message.
180  */
181  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
182  rle_get_error( rle_err, cmd_name( argv ), errname );
183 
184 
185  exit(0);
186 }
187 
188 void
190 int level;
191 pyramid * leftbandpyr, * rightbandpyr, *splitbandpyr;
192 {
193  int xsize, ysize, x, y, chan, xlinewidth, nchan;
194  rle_pixel *leftbase, *leftrastptr, *leftpxl, *leftsign;
195  rle_pixel *rightbase, *rightrastptr, *rightpxl, *rightsign;
196  rle_pixel *outbase, *outrastptr, *outpxl, *outsign;
197  float tval;
198  int rightval, leftval, outval;
199 
200  leftbase = leftbandpyr->corners[level];
201  rightbase = rightbandpyr->corners[level];
202  outbase = splitbandpyr->corners[level];
203  xsize = leftbandpyr->xlen[level];
204  ysize = leftbandpyr->ylen[level];
205  nchan = leftbandpyr->nchan - 1;
206  splitbandpyr->xlen[level] = xsize;
207  splitbandpyr->ylen[level] = ysize;
208  xlinewidth = xsize + MASKSIZE - 1;
209 
210  fprintf(stderr,"Copying half of level %d, size %d\n",level,xsize);
211  for (y = 0; y < ysize; y++)
212  {
213  leftrastptr = &(leftbase[MASKBELOW + (y+MASKBELOW) *
214  xlinewidth * (nchan+1)]);
215  rightrastptr = &(rightbase[MASKBELOW + (y+MASKBELOW) *
216  xlinewidth * (nchan+1)]);
217  outrastptr = &(outbase[MASKBELOW + (y+MASKBELOW) *
218  xlinewidth * (nchan+1)]);
219 
220  outsign = &(outrastptr[nchan * xlinewidth]);
221  for(x=0; x < xsize; x++)
222  {
223  *outsign = 0;
224  }
225 
226  for (chan = 0; chan < nchan; chan++)
227  {
228  leftpxl = &(leftrastptr[chan * xlinewidth]);
229  leftsign = &(leftrastptr[nchan * xlinewidth]);
230  rightpxl = &(rightrastptr[chan * xlinewidth]);
231  rightsign = &(rightrastptr[nchan * xlinewidth]);
232  outpxl = &(outrastptr[chan * xlinewidth]);
233  outsign = &(outrastptr[nchan * xlinewidth]);
234  for(x=0; x < xsize; x++)
235  {
236  /* should do some mask magic here */
237  if (x <= (15 * xsize / 32))
238  {
239  *outpxl = (*leftpxl);
240  if ((1 << chan) & (*leftsign))
241  *outsign |= (1 << chan);
242  }
243  else if (x >= (17 * xsize / 32))
244  {
245  *outpxl = (*rightpxl);
246  if ((1 << chan) & (*rightsign))
247  *outsign |= (1 << chan);
248  }
249  else
250  {
251  tval = ((float) x - (15.0 * (float) xsize / 32.0)) /
252  ((float) xsize / 16.0);
253  leftval = (int) (*leftpxl) *
254  (((1 << chan) & (*leftsign)) ? -1 : 1);
255  rightval = (int) (*rightpxl) *
256  (((1 << chan) & (*rightsign)) ? -1 : 1);
257  outval = (int) (tval * (float) rightval +
258  (1.0 - tval) * (float) leftval);
259  if (outval < 0)
260  {
261  *outpxl = (rle_pixel) (-outval);
262  *outsign |= (1 << chan);
263  }
264  else
265  *outpxl = (rle_pixel) (outval);
266  }
267  leftpxl++;
268  rightpxl++;
269  outpxl++;
270  leftsign++;
271  rightsign++;
272  outsign++;
273  }
274  }
275  }
276 }
277 
278 void
280 int level;
281 pyramid * leftbandpyr, * rightbandpyr, *splitbandpyr, *maskgausspyr;
282 {
283  int xsize, ysize, x, y, chan, xlinewidth, nchan;
284  rle_pixel *leftbase, *leftrastptr, *leftpxl, *leftsign;
285  rle_pixel *rightbase, *rightrastptr, *rightpxl, *rightsign;
286  rle_pixel *outbase, *outrastptr, *outpxl, *outsign;
287  rle_pixel *maskbase, *maskrastptr, *maskpxl;
288  float tval;
289  int rightval, leftval, outval;
290 
291  leftbase = leftbandpyr->corners[level];
292  rightbase = rightbandpyr->corners[level];
293  outbase = splitbandpyr->corners[level];
294  maskbase = maskgausspyr->corners[level];
295  xsize = leftbandpyr->xlen[level];
296  ysize = leftbandpyr->ylen[level];
297  nchan = leftbandpyr->nchan - 1;
298  splitbandpyr->xlen[level] = xsize;
299  splitbandpyr->ylen[level] = ysize;
300  xlinewidth = xsize + MASKSIZE - 1;
301 
302 /* fprintf(stderr,"Masking level %d, size %d\n",level,xsize); */
303  for (y = 0; y < ysize; y++)
304  {
305  leftrastptr = &(leftbase[MASKBELOW + (y+MASKBELOW) *
306  xlinewidth * (nchan+1)]);
307  rightrastptr = &(rightbase[MASKBELOW + (y+MASKBELOW) *
308  xlinewidth * (nchan+1)]);
309  outrastptr = &(outbase[MASKBELOW + (y+MASKBELOW) *
310  xlinewidth * (nchan+1)]);
311  maskrastptr = &(maskbase[MASKBELOW + (y+MASKBELOW) *
312  xlinewidth * nchan]);
313 
314  outsign = &(outrastptr[nchan * xlinewidth]);
315  for(x=0; x < xsize; x++)
316  {
317  *outsign = 0;
318  }
319 
320  for (chan = 0; chan < nchan; chan++)
321  {
322  leftpxl = &(leftrastptr[chan * xlinewidth]);
323  leftsign = &(leftrastptr[nchan * xlinewidth]);
324  rightpxl = &(rightrastptr[chan * xlinewidth]);
325  rightsign = &(rightrastptr[nchan * xlinewidth]);
326  outpxl = &(outrastptr[chan * xlinewidth]);
327  outsign = &(outrastptr[nchan * xlinewidth]);
328  maskpxl = &(maskrastptr[chan * xlinewidth]);
329  for(x=0; x < xsize; x++)
330  {
331  /* should do some mask magic here */
332  if (*maskpxl == 255) /* full coverage means left image */
333  {
334  *outpxl = (*leftpxl);
335  if ((1 << chan) & (*leftsign))
336  *outsign |= (1 << chan);
337  }
338  else if (*maskpxl == 0) /* no coverage means right image */
339  {
340  *outpxl = (*rightpxl);
341  if ((1 << chan) & (*rightsign))
342  *outsign |= (1 << chan);
343  }
344  else
345  {
346  tval = ((float) (*maskpxl)) / 255.0;
347  leftval = (int) (*leftpxl) *
348  (((1 << chan) & (*leftsign)) ? -1 : 1);
349  rightval = (int) (*rightpxl) *
350  (((1 << chan) & (*rightsign)) ? -1 : 1);
351  outval = (int) (tval * (float) leftval +
352  (1.0 - tval) * (float) rightval);
353  if (outval < 0)
354  {
355  *outpxl = (rle_pixel) (-outval);
356  *outsign |= (1 << chan);
357  }
358  else
359  *outpxl = (rle_pixel) (outval);
360  }
361  leftpxl++;
362  rightpxl++;
363  outpxl++;
364  maskpxl++;
365  leftsign++;
366  rightsign++;
367  outsign++;
368  }
369  }
370  }
371 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int * ylen
Definition: pyramid.h:24
#define MASKSIZE
Definition: pyramid.h:15
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
#define MASKBELOW
Definition: pyramid.h:16
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
#define RLE_EMPTY
Definition: rle.h:73
char * cmd_name(char **argv)
Definition: cmd_name.c:31
int levels
Definition: pyramid.h:28
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_to_pyramids()
#define RLE_SUCCESS
Definition: rle.h:70
static char rcs_ident[]
Definition: pyrmask.c:12
int rle_get_error(int code, const char *pgmname, const char *fname)
Definition: rle_error.c:76
void dump_pyramid()
void copy_mask_bands(int level, pyramid *leftbandpyr, pyramid *rightbandpyr, pyramid *splitbandpyr, pyramid *maskgausspyr)
Definition: pyrmask.c:279
int nchan
Definition: pyramid.h:26
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
void copy_half_bands(int level, pyramid *leftbandpyr, pyramid *rightbandpyr, pyramid *splitbandpyr)
Definition: pyrmask.c:189
void rebuild_image()
const char * cmd
Definition: rle.h:133
int * xlen
Definition: pyramid.h:24
void alloc_pyramid()
rle_pixel ** corners
Definition: pyramid.h:22
#define RLE_EOF
Definition: rle.h:74
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
unsigned char rle_pixel
Definition: rle.h:56
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86
float * gauss_mask(int siz)
Definition: smush.c:323